zoukankan      html  css  js  c++  java
  • PHP实现共享高速内存数据池(非MYSQL数据库) 类似asp的application

         为什么要实现这个共享内存池呢?
        因为PHP每一次请求,服务器调用一次PHP.EXE程序进行PHP文件的解析.之后该程序就会被关闭.所以不存在共享内存机制.懂asp的朋友应该知道,在asp内共享内存缓存可以使用application,但是php内没有,所以我们就研究一下让php也具备该能力.
         这共享内存池有什么用呢?
    做webgame的时候,最简单的功能聊天,这是需要所有用户共享的数据,一般的处理方法是写文本,或者写数据库,这样的效率很低,因为PHP程序,有80%的时候是等待数据库返回数据,对于用户的实时性要求相对高的聊天程序,就不能去这样占用MYSQL的数据库时间了,这些数据数据不需要永久保存,但是需要缓存,所以这个时候高速共享内存的作用就出来了.

    php有两套使用共享内存的函数,一套是System V IPC函数的封装,另一套是shmop。
    这两个都无需安装外部库文件。
    前者只能在linux下使用,而且要使用它的话,在安装php的时候要加上–enable-sysvshm选项;
    而后者在linux和windows(win2k之后的系统,win98不支持)都可以使用,但在windows的时候,只有在php是ISAPI运行模式才能正常工作,在安装php的时候要加上–enable-shmop。

    这两套函数的使用相当简单,下面分别给出简单的用法,更详细的信息可以参考php手册。

    System V的共享内存使用:

    $key = 12345; // 共享内存的key
    $memsize = 100; // 共享内存的大小,单位byte
    $perm = 0666; // 共享内存访问权限,参考linux的权限
    $var_key = 345; // 共享内存的某变量的key
    $shmid = shm_attach( $key, $memsize, $perm ); // 创建一个共享内存
    shm_put_var( $shmid, $var_key, "abc" ); // 插入一个共享内存变量,key为$var_key,值为"abc"
    shm_detach( $shmid ); // 关闭共享内存

    运行上面的php程序将创建一个key为12345的共享内存,大小为100字节,里面有个值为”abc”的变量。我们可以在linux命令行敲入ipcs看看我们所创建的共享内存:

    —— Shared Memory Segments ——–
    key             shmid         owner          perms         bytes         nattch        status      
    0×00003039      262144        daemon          666           100              0               

    0×00003039就是12345的16进制形式。
    我们再写另一个访问这个共享内存并删除这个共享内存的php:

    $shmid = shm_attach( 12345 ); // 访问key为12345的共享内存
    echo shm_get_var( $shmid, 345 ); // 把共享内存中key为345的变量打印出来,这里将显示abc
    shm_remove( $shmid ); // 删除该共享内存


    运行这个php,将显示abc,并把共享内存删除,这时候再运行ipcs就可以看到那块共享内存已经不存在了。

    shmop的共享内存使用:

    $key = 12345; // 共享内存的key
    $memsize = 100; // 共享内存的大小,单位byte
    $perm = 0666; // 共享内存访问权限,参考linux的权限
    $offset = 0; // 共享内存偏移地址,0表示共享内存的起始地址
    $shmid = shmop_open($key, "c", $perm, $memsize); // 创建一个共享内存,第二个参数c表示创建
    $shm_bytes_written = shmop_write($shm_id, "abc", 0); // 把"abc"写入共享内存
    echo $shm_bytes_written; // 打印出写入共享内存的数据长度,这里将显示3
    shmop_close($shm_id); // 关闭共享内存

    运行这个php将创建一个key为12345,大小为100字节的共享内存,里面写入了”abc”这个字符串。
    我们在写一个访问这个共享内存的php:

    $shm_id = shmop_open(12345, "w", 0, 0); // 打开key为12345的共享内存,第二个参数w表示以读写方式打开,打开已存在的共享内存,第三个和第四个参数必须是0
    $shm_data = shmop_read($shm_id, 0, 3); // 从共享内存里面读取3字节的数据,第二个参数是偏移地址,0表示共享内存的起始地址
    echo $shm_data; // 打印出上个函数返回的共享内存数据
    shmop_delete($shm_id); // 删除共享内存

    运行这个php将打印出abc,并把原来的共享内存删除。

    总结:

    这两套函数都是简单易用的,shmop的唯一好处是可以在windows下使用,在linux下的话本人强烈推荐使用shm_*那套函数,因为那套函数在插入、更新以及读取共享内存里面的变量相当方便,而shmop需要自己来规划共享内存的存储结构,应用起来稍微复杂一点。
    此外,上面的例子里面我直接用数字12345作为共享内存的key,实际上,更为标准的做法是使用ftok函数来把一个路径转成ipc的key。具体做法可以参考php手册。

    以上两个方案都不是很理想.好用的那个只支持LINUX.所以我们使用第三套共享内存.

    还有一套是我们这次要用到的是分布式缓存系统Memcached       [key-value内存缓存系统]
    下面来看一下介绍吧

    在PHP中使用Memcached,有两种方式,一种是安装PHP的memcache扩展(实际上还有另外一个memcached扩展,是基于比较流行的libmemcached库封装的),该扩展是用c写的,效率较高,需要在服务器上安装。另外一种则是直接使用客户端的php-memcached-client类库,但是这个我在网上找了半天也没找到一个官方的网站。所以呢,还是装个扩展吧。假设php安装在/home/admin/php目录:

    wget http://pecl.php.net/get/memcache-2.2.5.tgz
    gzip -d memcache-2.2.5.tgz
    tar xvf memcache-2.2.5.tar
    cd memcache-2.2.5
    /home/admin/php/bin/phpize
    Configuring for:
    PHP Api Version:         20041225
    Zend Module Api No:      20060613
    Zend Extension Api No:   220060519
    
    ./configure --enable-memcache --with-php-config=/home/admin/php/bin/php-config --with-zlib-dir
    Installing shared extensions:     /home/admin/php/lib/php/extensions/no-debug-non-zts-20060613/

    注意到最后一行返回的信息,将下面两行添加到/home/admin/php/lib/php.ini

    extension_dir = "/home/admin/php/lib/php/extensions/no-debug-non-zts-20060613/"
    extension=memcache.so

    然后重启web服务器即可。如果安装成功,则通过phpinfo()可以获得该扩展的相关信息:

    memcache support enabled
    Active persistent connections 0
    Version 2.2.5
    Revision $Revision: 1.111 $
    Directive Local Value Master Value
    memcache.allow_failover 1 1
    memcache.chunk_size 8192 8192
    memcache.default_port 11211 11211
    memcache.default_timeout_ms 1000 1000
    memcache.hash_function crc32 crc32
    memcache.hash_strategy standard standard
    memcache.max_failover_attempts 20 20

    以上参数都可以在php.ini中进行设置。下面是一段官方网站的php测试代码:

    <?php
    $memcache = new Memcache;
    $memcache->connect('127.0.0.1', 11211) or die ("Could not connect");
    $version = $memcache->getVersion();
    echo "Server's version: ".$version."\n";
    $tmp_object = new stdClass;
    $tmp_object->str_attr = 'test';
    $tmp_object->int_attr = 123;
    $memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server");
    echo "Store data in the cache (data will expire in 10 seconds)\n";
    $get_result = $memcache->get('key');
    echo "Data from the cache:\n";
    var_dump($get_result);
    ?>

    运行后输出如下:

    Server's version: 1.2.6
    Store data in the cache (data will expire in 10 seconds)
    Data from the cache: object(stdClass)#3 (2)
    { ["str_attr"]=>  string(4) "test" ["int_attr"]=>  int(123) }
    恩,这东西可以像SESSION那样使用,这正是我们需要的高速共享内存池,这东西是跨平台的.

  • 相关阅读:
    统计nginx日志里访问次数最多的前十个IP
    while 格式化输出 运算符 字符编码
    Python 软件安装
    Python 基础
    Typora 基础的使用方法
    Django ORM (四) annotate,F,Q 查询
    Django 惰性机制
    Django ORM (三) 查询,删除,更新操作
    Django ORM (二) 增加操作
    Django ORM (一) 创建数据库和模型常用的字段类型参数及Field 重要参数介绍
  • 原文地址:https://www.cnblogs.com/see7di/p/2239879.html
Copyright © 2011-2022 走看看