+
95
-

swoole内存表table有啥用?

swoole内存表table有啥用?

网友回复

+
15
-

原生PHP进程之间是不能相互通信的,在swoole_process中则是可以的,Swoole中进程之间的通信是通过管道pipe来传递的。多进程、多线程之间的数据共享则是通过内存memory来实现的。 swoole_table共享内存表是一个基于共享内存和锁实现的超高性能并发数据结构,用于解决多进程或多线程数据共享和同步加锁问题,它不消耗服务器 IO,纯内存操作,性能十分强悍。 swoole table优势 共享内存表可以直接操作系统的内存,性能强悍,单线程每秒可读写200万每次,主要用于进程间的数据通信。 共享内存表应用代码无需加锁,内置行锁自旋锁,所有操作都是多进程或多线程安全,用户层完全不需要考虑数据同步问题。 共享内存表支持多进程,内存表可以用于多进程之间共享数据。 共享内存表使用行锁而非全局锁,仅当两个进程在同一CPU时间并发读取同一条数据时才会发生抢锁。 共享内存表不受PHP的memory_limit最大内存的控制 适用场景:用于解决多进程或多线程数据共享和同步加锁问题,进程结束后共享内存表会自动释放。

示例代码

<?php
use Swoole\Table;

//创建共享内存表对象
$size = 1024;//2的n次方
$table = new swoole_table($size);

//共享内存表添加字段
$table->column("id", Table::TYPE_INT, 11);
$table->column("name", Table::TYPE_STRING, 20);
$table->column("money", Table::TYPE_FLOAT, 10);
$table->create();

//共享内存表添加行
$table->set("alice", ["id"=>1, "name"=>"alice", "money"=>100.5]);
//使用数组方式添加行
$table["ben"] =["id"=>2, "name"=>"ben", "money"=>200.1];

//获取行返回数组
$val = $table->get("alice");
var_dump($val);
//获取行返回对象
$val = $table["ben"];
var_dump($val);

//共享内存表内字段值增加
$table->incr("alice", "money", 100);
var_dump($table["alice"]);

//共享内存表中字段值减少
$table->decr("ben", "money", 50);
var_dump($table["ben"]);

echo json_encode($table).PHP_EOL;

方法解析

创建对象construct

创建共享内存表

function Table->__construct(int $size, float $conflict_propertion = 0.2);

共享内存表实际上是一个开链法实现的哈希表,内存是由哈希键Key与具体数据组成的数组,如果哈希冲突即不同的键值对一个同一个哈希,那么就会从内存池pool中分配出一个元素作为数组元素的链表尾。 内存表占用的内存总数 = ( 结构体长度 + 哈希键长度64byte + 行尺寸$size ) * 预留作为哈希冲突的百分比 * 列尺寸 参数1:int $size $size表示创建共享内存表时设置的最大行数,必须是2的次方,如果不是底层会自动调整为接近的一个数字,若小于1024则默认为1024,即1024为最小值。若机器内存不足内存表会创建失败。 共享内存表底层是建立在共享内存之上的哈希表HashTable(数据结构),最大行数$size决定了哈希表的总行数。由于内存表是在共享内存之上,所以无法动态扩容,因此$size必须在创建前提前设置好。 参数2:float $conflict_propertion 哈希冲突率

如果哈希冲突超过最大比例,共享内存表将不再允许添加新的行元素。共享内存表能存储的总数据行数取决于数据的哈希键冲突率,默认如果冲突率超过20%,预留的哈希hash冲突内存块容量不足,会报Unable to allocate memory无法分配内存的错误,并返回false表示存储失败。

<?php
use Swoole\Table;

//创建共享内存表对象
$size = 1024;//2的n次方
$table = new swoole_table($size);
$table->column("data", Table::TYPE_STRING, 1);
$table->create();

echo json_encode($table)...

点击查看剩余70%

+
15
-

在多进程模式下进程之间的内存是相互隔离的,在一个工作进程中的全局变量和超全局变量,在另一个工作进程中是无法读取和操作的。

如果只有一个工作进程,则不存在进程隔离问题,可以使用全局变量和超全局变量。 要实现进程间共享数据,我们可以使用第三方的 Redis 内存数据库或 Swoole 内置的 Table 共享内存来实现。

swoole 内存表Table 的优势

性能强悍,单线程每秒可读写 200 万次;

应用代码无需加锁,Table 内置行锁自旋锁,所有操作均是多线程 / 多进程安全。用户层完全不需要考虑数据同步问题;

支持多进程,Table 可以用于多进程之间共享数据;

使用行锁,而不是全局锁,仅当 2 个进程在同一 CPU 时间,并发读取同一条数据才会进行发生抢锁。

我们来用swoole的内存表实现类似memcache的缓存服务中间件,代码如下:

<?php
// 实例化一个占用的共享内存大小为1024的内存表
$table = new Swoole\Table(1024);
// 内存表增加3列
$table->column('fd', Swoole\Table::TYPE_INT);
$table->column('reactor_id', Swoole\T...

点击查看剩余70%

我知道答案,我要回答