从有序聚集随机取一个值,应该用什么方案?
percona-toolkit 之 【pt-query-digest】使用,percona-toolkit 之 【pt-query-digest】介绍,percona-toolkit 之 【pt-query-digest】介绍,percona-toolkit 之 【pt-query-digest】介绍
本日做了一个小试验,原由以下:
先在redis里组织了测试数据,以下:
> zadd my_zset_999 1 35570
(integer) 1
> zadd my_zset_999 2 40617
(integer) 1
> zadd my_zset_999 3 40956
(integer) 1
> zadd my_zset_999 4 41151
(integer) 1
>
> zrange my_zset_999 0 -1 WITHSCORES
1) "35570"
2) "1"
3) "40617"
4) "2"
5) "40956"
6) "3"
7) "41151"
8) "4"
>
> zrange my_zset_999 0 -1
1) "35570"
2) "40617"
3) "40956"
4) "41151"
测试要领就是很简单的盘算程序运转时候。
$t1 = microtime(true);
// 代码片断
$t2 = microtime(true);
$t = $t2 - $t1;
要领1
zrange
key 0 -1 掏出一切的值
array_rand() 从数组中随机掏出一个值
要领2
zcount
key -inf +inf 盘算该鸠合有多少个元素(cnt)
rand(1, cnt) 生成一个随机数(random)
zrangebyscore
key random random
要领3:对要领2的革新
zcard
key 盘算该鸠合有多少个元素(cnt)
rand(1, cnt) 生成一个随机数(random)
zrangebyscore
key random random
要领4:对要领1的革新
zrangebyscore
key -inf +inf
array_rand() 从数组中随机掏出一个值
要领 1 和要领 4 都是先掏出有序鸠合的一切值,再随机掏出一个值;
要领 2 和要领 3 则是随机从有序鸠合中掏出一个值。
下面是各要领的运转时候对照。
要领 2 和要领 3,即 zcount
和 zcard
的运转时候对照:
运转时候对照 | 要领2/zcount | 要领3/zcard |
---|---|---|
第1次 | 0.0072240829467773 | 0.007314920425415 |
第2次 | 0.0057311058044434 | 0.0071389675140381 |
第3次 | 0.0065360069274902 | 0.0071680545806885 |
第4次 | 0.0047309398651123 | 0.0075440406799316 |
第5次 | 0.0058040618896484 | 0.0068428516387939 |
第6次 | 0.0068061351776123 | 0.0073769092559814 |
第7次 | 0.0070509910583496 | 0.0070638656616211 |
第8次 | 0.008112907409668 | 0.0076460838317871 |
第9次 | 0.0070209503173828 | 0.0067050457000732 |
第10次 | 0.0069761276245117 | 0.0073142051696777 |
能够看出 zcount
比 zcard
的波动大,且用时长,所以镌汰要领2,这是由于 zcard
的时候复杂度是 O(1)
,而 zcount
的时候复杂度是 O(log(N))
。
要领 1 和要领 3,即 zrange
和 zrangebyscore
的运转时候对照:
运转时候对照 | 要领1/zrange | 要领3/zrangebyscore |
---|---|---|
第1次 | 0.0076210498809814 | 0.0040271282196045 |
第2次 | 0.0066070556640625 | 0.0056281089782715 |
第3次 | 0.0062861442565918 | 0.0061671733856201 |
第4次 | 0.0070350170135498 | 0.0064809322357178 |
第5次 | 0.0070219039916992 | 0.0068569183349609 |
能够看出要领 2 比要领 1 要快一些。那如果把要领 1 改成用 zrangebyscore
掏出一切值,再随机取元素呢,也就是要领 4,再比较要领 4 和要领 3 的运转时候:
运转时候对照 | 要领4/zrangebyscore掏出数组,随机掏出1一个值 | 要领3/zrangebyscore依据随机数掏出一个值 |
---|---|---|
第1次 | 0.0068261623382568 | 0.0075819492340088 |
第2次 | 0.0072751045227051 | 0.0073590278625488 |
第3次 | 0.0055849552154541 | 0.0072290897369385 |
第4次 | 0.0048110485076904 | 0.0075399875640869 |
第5次 | 0.0073840618133545 | 0.0075678825378418 |
第6次 | 0.0072331428527832 | 0.0072460174560547 |
第7次 | 0.007411003112793 | 0.0074880123138428 |
第8次 | 0.0062360763549805 | 0.007282018661499 |
第9次 | 0.0077290534973145 | 0.0074591636657715 |
第10次 | 0.0068199634552002 | 0.0074419975280762 |
能够看到要领 4 比要领 3 快一些,再用 ab
测试东西测一下
# 模仿100个并发用户,对一个资本发送100个要求。
ab -c 100 -n 100 url
要领 4 的测试效果以下:
Server Software: nginx/1.15.11
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: test1.php
Document Length: 38 bytes
Concurrency Level: 100
Time taken for tests: 0.520 seconds
Complete requests: 100
Failed requests: 0
Non-2xx responses: 100
Total transferred: 23400 bytes
HTML transferred: 3800 bytes
Requests per second: 192.25 [#/sec] (mean)
Time per request: 520.161 [ms] (mean)
Time per request: 5.202 [ms] (mean, across all concurrent requests)
Transfer rate: 43.93 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 18 25 5.6 26 35
Processing: 41 219 87.1 219 359
Waiting: 41 219 87.4 219 359
Total: 60 245 92.3 246 393
Percentage of the requests served within a certain time (ms)
50% 246
66% 296
75% 326
80% 340
90% 372
95% 392
98% 392
99% 393
100% 393 (longest request)
要领 3 的测试效果以下:
Server Software: nginx/1.15.11
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /test2.php
Document Length: 38 bytes
Concurrency Level: 100
Time taken for tests: 0.526 seconds
Complete requests: 100
Failed requests: 0
Non-2xx responses: 100
Total transferred: 23400 bytes
HTML transferred: 3800 bytes
Requests per second: 189.97 [#/sec] (mean)
Time per request: 526.390 [ms] (mean)
Time per request: 5.264 [ms] (mean, across all concurrent requests)
Transfer rate: 43.41 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 16 23 3.8 25 31
Processing: 36 216 89.5 220 372
Waiting: 36 216 89.2 220 372
Total: 54 239 92.9 245 403
Percentage of the requests served within a certain time (ms)
50% 245
66% 295
75% 316
80% 333
90% 362
95% 374
98% 402
99% 403
100% 403 (longest request)
经由过程 Time taken for tests
、Requests per second
等效果,能够看出要领 4 比要领 3 的机能更高一些。
也就是先掏出一切元素,再随机掏出一个值 和 组织一个随机数掏出一个元素 这两种计划,前者更好一些。
到这里就完毕了吗?并没有~
终究效果就是不采纳有序鸠合这类数据结构了,用列表或鸠合这类数据结构即可。由于有序鸠合 zset
还要组织 score
值,比方插进去元素,要查出最大的score值,再加 1。
既然需求只是从一堆元素中随机取一个值,用列表或鸠合这类数据结构就可以满足所需了。
软工热身博客