zoukankan      html  css  js  c++  java
  • swoole_table

    swoole_table
    swoole_table是一个基于共享内存和锁实现的超高性能,并发数据结构。用于解决多进程/多线程数据共享和同步加锁问题。 使用swoole_table可以方便的共享数据,而不用担心数据同步问题,不需要用户层加锁,不需要考虑锁的开销。
    swoole_table使用行锁,而不是全局锁,仅当2个进程在同一CPU时间,并发读取同一行数据才会进行发生抢锁。

    > swoole_table在swoole 1.7.5版本后可用<br>
    swoole_table-0.1版本,单进程压测每秒可读写50W次左右<br>

    #常量列表


    swoole_table 目前只支持以下3种类型,个人感觉有点儿类似于表字段类型。
    * swoole_table::TYPE_INT 整形字段
    * swoole_table::TYPE_FLOAT 浮点字段
    * swoole_table::TYPE_STRING 字符串字段

    # 函数列表

    * [__construct](#__construct)
    * [column](#column)
    * [create](#create)
    * [set](#set)
    * [get](#get)
    * [del](#del)
    * [lock](#lock)
    * [unlock](#unlock)

    ## __construct
    **功能描述**:内存表构造函数,创建内存表对象对象。
    **函数原型**
    ```php
    swoole_table->__construct(int $size)
    ```
    **返回**:一个swoole_table对象。
    **参数说明**

    | 参数 | 说明 |
    | -------- | -------- |
    | int size | 表格的最大行数 |
    **说明**
    * 创建对象后会创建一个Mutex锁。
    * $table->lock()/$table->unlock() 在这之后即可使用。

    > swoole_table基于行锁,所以单次set/get/del在多线程/多进程的环境下是安全的
    set/get/del是原子操作,用户代码中不需要担心数据加锁和同步的问题

    **样例**
    ```php
    $table = new swoole_table(1024);
    ```

    ## column
    **功能描述**:给内存表增加一列
    **函数原型**
    ```php
    bool swoole_table->column(string $name, int $type, $size);
    ```

    **参数说明**

    | 参数 | 说明 |
    | -------- | -------- |
    | string name | 新增的字段名称 |
    | int type | swoole_table支持的3种字段类型,详情见[常量列表](#%E5%B8%B8%E9%87%8F%E5%88%97%E8%A1%A8) |
    | int size | 这是根据type的不同占用的字节数 |

    **说明**

    > swoole_table::TYPE_INT默认为4个字节,可以设置1,2,4,8一共4种长度
    swoole_table::TYPE_STRING设置后,set操作不能设置的值不能超过此长度
    swoole_table::TYPE_FLOAT会占用8个字节的内存

    **样例**
    ```php
    $table->column('id', swoole_table::TYPE_INT, 4);
    ```

    ## create
    **功能描述**:创建内存表。
    **函数原型**
    ```php
    swoole_table->create()
    ```
    **说明**
    创建好表的结构后,执行create后创建表。

    > swoole_table使用共享内存来保存数据,在创建子进程前,务必要执行swoole_table->create()
    swoole_server中使用swoole_table,swoole_table->create() 必须在swoole_server->start()前执行

    **样例**
    ```php
    $table = new swoole_table(1024);
    $table->column('id', swoole_table::TYPE_INT, 4); //1,2,4,8
    $table->column('name', swoole_table::TYPE_STRING, 64);
    $table->column('num', swoole_table::TYPE_FLOAT);
    $table->create();

    $worker = new swoole_process('child1', false, false);
    $worker->start();
    ```

    ## set
    **功能描述**:设置行的数据,(swoole_table使用key-value的方式来访问数据,个人感觉key类似于db表记录的id,value则是整条记录的所有列的值。)
    **函数原型**
    ```php
    swoole_table->set(string $key, array $value)
    ```

    **参数说明**

    | 参数 | 说明 |
    | -------- | -------- |
    | string key | 数据的key,相同的$key对应同一行数据,如果set同一个key,会覆盖上一次的数据 |
    | array $value | 必须是一个数组,value中的键名必须与字段定义的$name完全相同 |

    **说明**

    > swoole_table->set() 可以设置全部字段的值,也可以只修改部分字段
    swoole_table->set() 未设置前,该行数据的所有字段均为空

    ## get
    **功能描述**:获取一行数据。
    **函数原型**
    ```php
    array swoole_table->get($key);
    ```

    **返回**
    * 如果找到则返回array 数组。
    * 如果$key不存在,将返回false

    ## del

    **功能描述**:删除一行数据。
    **函数原型**
    ```php
    bool swoole_table->del(string $key)
    ```

    **返回**
    * $key对应的数据不存在,将返回false
    * 成功删除返回true

    ## lock

    **功能描述**:锁定整个表。
    **函数原型**
    ```php
    swoole_table->lock()
    ```

    **使用场景**:当多个进程同时要操作一个事务性操作时,一定要加锁,将整个表锁定。操作完成后释放锁。
    **说明**
    * lock() 是互斥锁,所以只能保护lock/unlock中间的代码是安全的。lock/unlock之外的操作是不能保护的。
    * set/get/del操作不使用互斥锁,所以lock之后无法阻止其他进程调用这些函数。

    **注意**

    > lock/unlock必须成对出现,否则会发生死锁,这里务必要小心
    lock/unlock之间不应该加入太多操作,避免锁的粒度太大影响程序性能
    lock/unlock之间的代码,应当try/catch避免抛出异常导致跳过unlock发生死锁

    ## unlock

    **功能描述**:释放锁。
    **函数原型**
    ```php
    swoole_table->unlock()
    ```
    ## 整体使用案例
    ```php
    $table = new swoole_table(1024);
    $table->column('id', swoole_table::TYPE_INT, 4); //1,2,4,8
    $table->column('name', swoole_table::TYPE_STRING, 64);
    $table->column('num', swoole_table::TYPE_FLOAT);
    $table->create();

    $table->set('tianfenghan@qq.com', array('id' => 145, 'name' => 'rango', 'num' => 3.1415));
    $table->set('350749960@qq.com', array('id' => 358, 'name' => "Rango1234", 'num' => 3.1415));
    $table->set('hello@qq.com', array('id' => 189, 'name' => 'rango3', 'num' => 3.1415));

    $data = $table->get('350749960@qq.com');
    $table->del('hello@qq.com');
    $table->lock();
    /**
    事务性处理。
    **/
    $table->unlock();

    count($table); // 获得有多少条记录。
    ```
    个人感觉如果要是可以获得table里所有的key就好了,因为get是要根据key来获取记录的。

  • 相关阅读:
    MySQL中的字符串函数
    用google map实现周边搜索功能
    用 wait-notify 写一段代码来解决生产者-消费者问题
    equals和hashcode为什么要一起重写
    Java知多少(107)几个重要的java数据库访问类和接口
    Java知多少(106)程序与数据库连接
    Java知多少(105)套接字(Socket)
    Java知多少(104)网络编程之统一资源定位符URL
    Java知多少(103)网络编程之IP地址和InetAddress类
    Java知多少(102)多媒体基础
  • 原文地址:https://www.cnblogs.com/yimingwang/p/9540329.html
Copyright © 2011-2022 走看看