亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

PHP操作redis集群

標簽:
PHP

一. 概述

目前我们用到的 php 的 redis 扩展 主要有2个,


二. phpredis(PHP扩展)方式

1. phpredis单机方式

<?php$client = new Redis();
$client->connect('10.30.5.163', '7000');echo $client->get('new_item_key:d89b561fb759fd533a8c2781ef15dd5f');

2.  phpredis集群使用


<?php$redis_list = ['10.30.5.162:7000','10.30.5.163:7000','10.30.5.163:7001'];
$client = new RedisCluster(NUll,$redis_list);echo $client->get('new_item_key:d89b561fb759fd533a8c2781ef15dd5f');
  • 代码说明
    第一个参数传NULL 别问我,我也不知道为啥。反正文档没找到,这篇也没看懂。
    第二个参数是我们需要连接的redis cluster的master服务器列表。我们有3个master,就填3个, 填一个主节点也行, 甚至填一个从节点也行, 但是性能有差异, 见第四部分

3. 集群原理

为甚么填入任何一个节点地址都可以操作redisCluster呢?

  • 在集群模式下,Redis接收任何键相关命令时首先计算键对应的槽,
    假如初始化的是从节点,  首先会向从节点发送redis命令,
    从节点根据槽找出所对应的节点,如果节点是自身,则处理键命令;
    如果不是自身,  则MOVED重定向错误,通知客户端请求正确的节点。这个过程称为MOVED重定向


    webp

    redis开发和运维.png

  • 重定向信息包含了键所对应的槽以及负责该槽的节点地址,根据这些信
    息客户端就可以向正确的节点发起请求

  • phpredis客户端可以根据重定向信息直接再次向键所在节点发起请求, 从而获取数据

图片来源: <<redis开发和运维>>

4. 设定超时

<?php$redis_list = ['10.30.5.162:7000','10.30.5.163:7000','10.30.5.163:7001', 1.5, 1.5];
$client = new RedisCluster(NUll,$redis_list);echo $client->get('new_item_key:d89b561fb759fd533a8c2781ef15dd5f');

timeout和read_timeout功能。就是加到master列表的后面。

timeout表示连接redis的最长时间,这里设为1.5秒,表示超过1.5秒要是还没连接成功就返回false 。

read_timeout表示连接redis成功后,读取一个key的超时时间,有时候读取一个key 可能value比较大,读取需要很长时间,这里设置1.5秒,表示要是过了1.5秒还没读取到数据就返回false。

三. PRedis方式

predis是一套用php代码写的php连接redis的扩展

<?phpuse Predis\Client;require __DIR__ . '/../vendor/autoload.php';// 写一个节点也可以$redis_list = [        'tcp://10.30.5.163:7000',        'tcp://10.30.5.163:7001',        'tcp://10.30.5.162:7000'];

$redis = new Client($redis_list, ['cluster'=>'redis']);echo $redis->get('new_item_key:d89b561fb759fd533a8c2781ef15dd5f');

四.  phpredis和Predis性能对比

  • 使用ab压测, 获取key
    /usr/local/apache2/bin/ab -n10000 -c100 http://10.30.5.162/redis.php

  • key:
    new_item_key:d89b561fb759fd533a8c2781ef15dd5f
    分布在10.30.5.163:7000节点

  • php.ini开启opcache

realpath_cache_size = 2M
[opcache]
zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.fast_shutdown=1
opcache.validate_timestamps=1
opcache.revalidate_freq=60
opcache.use_cwd=1
opcache.max_accelerated_files=100000
opcache.max_wasted_percentage=5
opcache.memory_consumption=128
opcache.consistency_checks=0
opcache.huge_code_pages=1

1. phpredis填入三个主节点

<?php$redis_list = ['10.30.5.162:7000','10.30.5.163:7000','10.30.5.163:7001',1.5,1.5]; 
$client = new RedisCluster(NUll,$redis_list);echo $client->get('new_item_key:d89b561fb759fd533a8c2781ef15dd5f');

测试结果

Concurrency Level:      100Time taken for tests:   2.203 secondsComplete requests:      10000Failed requests:        12
   (Connect: 0, Receive: 0, Length: 12, Exceptions: 0)Total transferred:      2506988 bytesHTML transferred:       509388 bytesRequests per second:    4539.89 [#/sec] (mean)Time per request:       22.027 [ms] (mean)Time per request:       0.220 [ms] (mean, across all concurrent requests)Transfer rate:          1111.47 [Kbytes/sec] received

吞吐量4500左右

2. phpredis只填入一个从节点

<?php$redis_list = ['10.30.5.161:7000'];

$client = new RedisCluster(NUll,$redis_list);echo $client->get('new_item_key:d89b561fb759fd533a8c2781ef15dd5f');

每次都会重定向

Concurrency Level:      100Time taken for tests:   9.726 secondsComplete requests:      10000Failed requests:        77
   (Connect: 0, Receive: 0, Length: 77, Exceptions: 0)Total transferred:      2490673 bytesHTML transferred:       506073 bytesRequests per second:    1028.14 [#/sec] (mean)Time per request:       97.263 [ms] (mean)Time per request:       0.973 [ms] (mean, across all concurrent requests)Transfer rate:          250.07 [Kbytes/sec] received

吞吐量1028(有点低啊)

3. 使用单机模式连接

<?php$redis_list = 'tcp://10.30.5.163:7000';

$client = new Redis();
$client->connect('10.30.5.163', '7000');echo $client->get('new_item_key:d89b561fb759fd533a8c2781ef15dd5f');

结果

Concurrency Level:      100Time taken for tests:   1.238 secondsComplete requests:      10000Failed requests:        0Total transferred:      2510000 bytesHTML transferred:       510000 bytesRequests per second:    8078.76 [#/sec] (mean)Time per request:       12.378 [ms] (mean)Time per request:       0.124 [ms] (mean, across all concurrent requests)Transfer rate:          1980.24 [Kbytes/sec] received

4. 使用predis集群模式

<?phpuse Predis\Client;require __DIR__ . '/../vendor/autoload.php';

$redis_list = [        'tcp://10.30.5.163:7000',        'tcp://10.30.5.163:7001',        'tcp://10.30.5.162:7000'];

$redis = new Client($redis_list, ['cluster'=>'redis']);echo $redis->get('new_item_key:d89b561fb759fd533a8c2781ef15dd5f');

结果

Concurrency Level:      100Time taken for tests:   5.380 secondsComplete requests:      10000Failed requests:        0Total transferred:      2510000 bytesHTML transferred:       510000 bytesRequests per second:    1858.68 [#/sec] (mean)Time per request:       53.802 [ms] (mean)Time per request:       0.538 [ms] (mean, across all concurrent requests)Transfer rate:          455.59 [Kbytes/sec] received

性能和phpredis差一倍, 但是是在开启opcache的情况下, 因为加载predis的client, 需要使用psr-4查找文件, 不开启opcache, 性能会差挺多, 有兴趣可以自己尝试

  • 总结
    使用phpredis操作集群性能和单机相差一倍左右, predis和phpredis差距有点大, 在实际编程中可以按需要去选择

  • 在java操作redis集群的库使用jedis, 可以为每一个节点设置一个连接池, 在发送请求前, 先计算槽, 根据本地缓存的槽和节点映射缓存就可以直接去请求数据保存的节点获取数据, 当槽和节点映射关系不正确, 会触发重试机制, 将最新的映射关系更新到缓存中
    php一次请求过后, 变量的生命周期就结束了, 无法设置连接池以及使用槽节点缓存机制,  命令如果和请求节点不对应, 就会MOVED重定向, 产生性能损耗.

附录 redis扩展安装

~ git clone [email protected]:phpredis/phpredis.git

~ cd phpredis

~ git fetch

~ git checout feature/redis_cluster #切换到cluster分支~ phpize

~ ./configure

~ make

~ make install

这样就可以用了。如果你是第一次安装redis扩展,还需要在php.ini中加上:

extension=redis.so



作者:其实我很dou
链接:https://www.jianshu.com/p/d786a1c8d2be


點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消