一. 压测环境
1台3u8机器(PHP-C3)、1台lg 3u8机器(PHP-LG):运行PHP脚本,发起codis读写请求
3台3u8机器(CODIS-C3):codis集群,运行1个proxy实例、2组redis(每组1主2从),proxy与redis混部
二. 压测方式
1. 在PHP-C3、PHP-LG机器起多个PHP进程,以模拟并发请求;
2. 每个PHP进程循环、同步发起codis请求;
3. 每个codis请求使用的key、value是随机生成的,key长度为50byte,value长度为100byte;
4. 耗时统计是在PHP端做的,另只统计了PHP-C3上的请求耗时,PHP-LG机器涉及到跨机房调用,所需耗时增加跨机房RTT即可.
三. 压测结果
1. codis写操作
并发数 |
PHP机器load |
Codis机器load |
QPS |
最小耗时 |
最大耗时 |
平均耗时 |
99%耗时 |
c3: 5 |
0.01 |
0.11 |
11000 |
0.219ms |
186.194ms |
0.386ms |
0.629ms |
c3: 10 |
0.63 |
0.22 |
19000 |
0.212ms |
221.679ms |
0.434ms |
0.875ms |
c3: 20 |
10.26 |
0.11 |
24600 |
0.218ms |
510.217ms |
0.739ms |
1.509ms |
c3: 20 lg: 20 |
c3: 11.56 lg: 0.02 |
0.16 |
37000 |
0.223ms |
390.256ms |
0.732ms |
1.498ms |
c3: 20 lg:40 |
c3: 11.52 lg: 0.81 |
0.18 |
47500 |
0.226ms |
503.914ms |
0.752ms |
1.525ms |
c3: 20 lg: 50 |
c3: 8.71 lg: 15.44 |
0.11 |
48500 |
0.223ms |
201.484ms |
0.732ms |
1.505ms |
结论:
(1) Codis在后端挂2组redis下,1个proxy实例的写操作能到48500/s,由于到并发70时,PHP-C3、PHP-LG机器负载已经较高,所以Codis的实际写处理能力可能比48500/s还更高点.
(2) 平均耗时在1ms以内.
2. codis读操作
并发数 |
PHP机器load |
Codis机器load |
QPS |
最小耗时 |
最大耗时 |
平均耗时 |
99%耗时 |
c3: 5 |
0.43 |
0.14 |
19500 |
0.208ms |
201.627ms |
0.429ms |
0.756ms |
c3: 10 |
0.41 |
0.25 |
21000 |
0.211ms |
202.139ms |
0.463ms |
0.894ms |
c3: 20 |
13.31 |
0.3 |
30500 |
0.214ms |
200.854ms |
0.66ms |
1.245ms |
c3: 20 lg: 20 |
c3: 14.84 lg: 0.22 |
0.14 |
43500 |
0.219ms |
28.686ms |
0.632ms |
1.014ms |
c3: 20 lg: 40 |
c3: 13.74 lg: 8.78 |
0.27 |
56100 |
0.22ms |
202.118ms |
0.616ms |
1.204ms |
c3: 20 lg: 50 |
c3: 10.81 lg: 9.19 |
0.19 |
58200 |
0.223ms |
40.478ms |
0.623ms |
1.265ms |
结论:
(1) Codis在后端挂2组redis下,1个proxy实例的读操作能到58200/s,由于到并发70时,PHP-C3、PHP-LG机器负载已经较高,所以Codis的实际读处理能力可能比58200/s还更高点.
(2) 平均耗时在1ms以内.
3. codis扩容、数据迁移对读写性能的影响
codis数据迁移分为2个阶段:
(1)pre-migrate阶段:codis整个集群的状态信息存储在zookeeper,每个proxy从zookeeper同步集群状态信息。由于同步速度有快慢,每个proxy的状态可能在某一时间点会不一致,在状态不一致的情况下做数据迁移操作,会导致数据不一致。所以codis设计了一个pre-migrate阶段,将需要迁移的slot先标记为pre-migrate,等所有proxy都同步到了这个pre-migrate状态,才发起下一步真正的数据迁移操作。
若slot被标记为pre-migrate,proxy会拒绝对该slot的写操作,所以在该阶段,会影响线上的写操作.
(2)migrate阶段:当所有proxy都将要迁移的slot标记为pre-migrate后,codis再将该slot标记为migrate,此时可进行真正的数据迁移了。proxy接收到某个key的读写请求时,若该key落在被标记为migrate的slot,则先发slotmigratekey命令,保证该key的数据已迁移到新的redis group,然后再将读写请求路由到新的redis group.
因此在数据迁移的migrate阶段,若请求落在正在迁移的slot,会多一次slotmigratekey的操作.
也就是从理论上讲,会有以下2点影响:
(1)在pre-migrate阶段,被迁移的slot上的写请求将会被拒绝。该阶段持续时间特别短,对线上影响不大.
(2)在migrate阶段,被迁移的slot上的所有读写请求将增加slotmigratekey操作,一定程度上加大处理耗时。由于迁移单位是slot,总共有1024个slot,也就是说线上的1/1024的请求处理耗时会增大.
实际压测结果:
操作类别 |
并发数 |
Codis机器load |
QPS |
最小耗时 |
最大耗时 |
平均耗时 |
99%耗时 |
write |
20 |
0.14 |
24500 |
0.218ms |
960.166ms |
0.738ms |
1.706ms |
read |
20 |
0.07 |
29800 |
0.211ms |
522.158ms |
0.648ms |
1.217ms |
结论:
(1) 没有出现由于pre-migrate阶段拒绝写请求,从而写失败的情况.
(2) QPS略有所下降,但下降幅度很低;最大耗时有所增加.
总体来说,数据迁移对读写请求没有特别大影响.
调整了下codis集群,proxy单独部署,1台proxy,1组redis(1主、1从),codis没有读写分离机制,也就是所有读写请求会全落到主redis。
压测结果如下:
纯读操作(QPS):27W/s
纯写操作(QPS):11W/s