Swoole/table优势
- 性能强悍,单线程每秒可读写 200 万次;
- 代码无需加锁,Table 内置行锁自旋锁,所有操作均是多线程/多进程安全。用户层完全不需要考虑数据同步问题;
- 支持多进程,Table 可以用于多进程之间共享数据;
- 使用行锁,而不是全局锁,仅当2个进程在同一 CPU时间,并发读取同一条数据才会进行发生抢锁。
use Swoole\Process;
use Swoole\Coroutine;
use Swoole\Table;
// 共享内容一经设置无法扩容,底层建立在共享内存上
// $size应是2的N次方,最小值64,table的最大行数略小于$size
$table = new Table($size = 1024);
// 给表格增加一列$file_name,类型为$type,最大长度为$size;
$table->column($file_name1 = 'int1', $file_type1 = Table::TYPE_INT); // 默认占8个字节
$table->column($file_name2 = 'float1', $file_type2 = Table::TYPE_FLOAT); // 占用8个字节
$table->column($file_name3 = 'string1', $file_type3 = Table::TYPE_STRING, $size = 1024); // 不能超过$size指定的最大长度,超出时底层自动截断
// 创建内存表,创建后不能再添加列
if (!$table->create()) {
echo '系统内存不足';
}
var_dump('表格最大行数:' . $table->size);
var_dump('表格占用内容(字节):' . $table->memorySize);
$worker1 = new Process(function ($process) use ($table) {
// 在表格中添加一行;相同的$key为同一行,多次添加会覆盖;$key不能超过63字节;数组数组必须与添加的列名称相同
if (!$table->set($key = '1', array('int1' => 1, 'float1' => 1.12, 'string1' => '测试1'))) {
echo '添加失败,内存不足';
}
if (!$table->set($key = '2', array('int1' => 2, 'string1' => '测试2'))) {
echo '添加失败,内存不足';
}
$table->set($key = '3', array('int1' => 3, 'float1' => 1.32));
// 对$key的指定列$field_name自增$incrby,自增自减只能对整型和浮点型列处理,且自增自减的值要对应列的类型
$table->incr($key = '3', $field_name = 'int1', $incrby = 1);
// 对$key的指定列$field_name自减$incrby
$table->decr($key = '3', $field_name = 'float1', $incrby = 1.0);
});
$worker1->start();
$worker2 = new Process(function ($process) use ($table) {
while (1) {
var_dump('表格中的行数:' . $table->count());
foreach ($table as $key1 => $value) {
// 检查table是否存在指定$key
if ($table->exist($key = '1')) {
// 删除指定$key的数据
$table->del($key = '1');
}
// 获取表格中指定的$key的一行或一个字段的数据
$table->get($key1, $field_name = null);
var_dump($value);
}
Coroutine::sleep(1);
}
}, false, 1, true);
$worker2->start();
while ($status = Process::wait(true)) {
echo "Recycled #{$status['pid']}, code={$status['code']}, signal={$status['signal']}" . PHP_EOL;
}