dig*_*tum 3 java lua redis lettuce
对于 Redis 中可能存在或不存在的聚合对象的集合,我想对它们调用 INCRBY 和 EXPIRE。从我的阅读来看,似乎使用MULTI或EVAL是要走的路。在对聚合对象执行INCRBY和EXPIRE操作之后,我需要取回从 INCRBY 操作返回的每个聚合的更新计数。我正在使用 Lettuce 客户端并寻找如何最好地执行此操作的示例。为简单起见,假设聚合对象类似于:
public class Aggregate {
private String id; // key in Redis
private Long count; // INCRBY operates on
}
Run Code Online (Sandbox Code Playgroud)
好吧,很难给你一个明确的答案,因为结果在很大程度上取决于多种因素:
n命令,这些时间会成倍增加。incrby,然后expire从作家和get读者,最糟糕的事情可能发生就是什么都没有,我猜。但是如果有其他读者修改但没有过期,那么你可能会错误地过期(writer1> incrby, writer2> set, writer1> expire)。如果您确定您只有第一种类型的编写器,那么您可以节省原子性。此外,您可能需要针对吞吐量或延迟进行优化。并且专门针对您的环境。正如您稍后将看到的,在不同的设置中会出现不同的方法。
EVAL(增加,过期)。我们发布一个 Lua 脚本来完成这项工作。优点:Redis 保证了 Lua 的原子性。缺点:我们需要一遍又一遍地发送脚本正文。EVAL(获取,setex)。相同,但我们可以使用不同的命令来完成这项工作。这些将在基准测试的末尾使用 'gs' 调用。EVALSHA. 我们可以先加载脚本主体,然后只发送它的摘要。优点:命令中的字节更少。缺点:需要确保没有人突然SCRIPT FLUSH把你的脚本带走,而且随着大量的脚本查找时间可能会增加。我预计这会是一个明显的赢家,但脚本足够小,不会成为连接的负担。MULTI. 我们可以在事务中发出命令。这一次 Redis 会暂存它们,直到您发出EXEC. 这是一个很大的开销,仅用于完整性。EXPIRE. 优点:感觉聪明。这是代码。
你真的应该自己运行它来优化你的需求。我注意到代码中定义的一些选项被忽略,因此请使用命令行参数。
不过,我会发布我的结果。我用 1 个线程为 3 种不同的连接类型运行它:本地 unix 套接字、本地 TCP、远程 TCP。不幸的是,远程主机的CPU单线程性能要弱得多,所以我必须将其本地结果发布以供参考。不幸的是,这个遥控器上有很多东西在运行,所以它的结果可能会受到影响。
Benchmark (address) Mode Cnt Score Error Units
RedisBatchesBenchmark.async socket thrpt 50 39722.167 ± 796.830 ops/s
RedisBatchesBenchmark.async_flush socket thrpt 50 37973.392 ± 239.880 ops/s
RedisBatchesBenchmark.evalsha socket thrpt 50 35697.480 ± 216.258 ops/s
RedisBatchesBenchmark.eval socket thrpt 50 34616.848 ± 238.412 ops/s
RedisBatchesBenchmark.evalshags socket thrpt 50 32642.795 ± 129.305 ops/s
RedisBatchesBenchmark.evalgs socket thrpt 50 31679.147 ± 150.264 ops/s
RedisBatchesBenchmark.naive socket thrpt 50 20935.985 ± 124.092 ops/s
RedisBatchesBenchmark.multi socket thrpt 50 19133.523 ± 72.581 ops/s
RedisBatchesBenchmark.async localhost thrpt 50 39179.742 ± 1457.819 ops/s
RedisBatchesBenchmark.async_flush localhost thrpt 50 33647.195 ± 295.427 ops/s
RedisBatchesBenchmark.evalsha localhost thrpt 50 30679.493 ± 109.669 ops/s
RedisBatchesBenchmark.eval localhost thrpt 50 29680.750 ± 161.762 ops/s
RedisBatchesBenchmark.evalshags localhost thrpt 50 28069.431 ± 158.887 ops/s
RedisBatchesBenchmark.evalgs localhost thrpt 50 27142.783 ± 69.314 ops/s
RedisBatchesBenchmark.naive localhost thrpt 50 17934.587 ± 152.859 ops/s
RedisBatchesBenchmark.multi localhost thrpt 50 15220.863 ± 32.219 ops/s
RedisBatchesBenchmark.evalsha remote thrpt 50 4001.585 ± 12.200 ops/s
RedisBatchesBenchmark.evalgs remote thrpt 50 3966.271 ± 16.590 ops/s
RedisBatchesBenchmark.async_flush remote thrpt 50 3867.448 ± 153.232 ops/s
RedisBatchesBenchmark.eval remote thrpt 50 3622.256 ± 246.454 ops/s
RedisBatchesBenchmark.evalshags remote thrpt 50 3607.975 ± 251.802 ops/s
RedisBatchesBenchmark.async remote thrpt 50 2681.453 ± 13.451 ops/s
RedisBatchesBenchmark.naive remote thrpt 50 2014.806 ± 5.630 ops/s
RedisBatchesBenchmark.multi remote thrpt 50 1344.477 ± 3.375 ops/s
------------
Remote host:
Benchmark (address) Mode Cnt Score Error Units
RedisCommandPacking.naive socket thrpt 25 11605,994 ± 368,055 ops/s
RedisCommandPacking.naive localhost thrpt 25 9477,190 ± 239,817 ops/s
Run Code Online (Sandbox Code Playgroud)
我们在这里看到什么?
不等待过期结果很快,但是当我们添加延迟(仅 0.194ms ping)时EVALSHA就会提前。请注意即使是最小的延迟也会影响如此快速操作的性能。即使考虑到较慢的 CPU,我们也损失了 5 倍。
两个命令不足以从手动刷新中获得提升(但请注意,我们不会等待过期结果。如果我们等待可能会有所不同)。
Benchmark (address) Mode Cnt Score Error Units
RedisBatchesBenchmark.async_flush socket thrpt 50 97904.168 ± 2497.354 ops/s
RedisBatchesBenchmark.async socket thrpt 50 95156.162 ± 1556.060 ops/s
RedisBatchesBenchmark.evalsha socket thrpt 50 66418.081 ± 1236.815 ops/s
RedisBatchesBenchmark.eval socket thrpt 50 63202.798 ± 1807.753 ops/s
RedisBatchesBenchmark.evalshags socket thrpt 50 55259.215 ± 1771.674 ops/s
RedisBatchesBenchmark.evalgs socket thrpt 50 54047.418 ± 1143.995 ops/s
RedisBatchesBenchmark.naive socket thrpt 50 37771.010 ± 1378.210 ops/s
RedisBatchesBenchmark.async localhost thrpt 50 71901.709 ± 1041.603 ops/s
RedisBatchesBenchmark.async_flush localhost thrpt 50 66513.162 ± 1353.913 ops/s
RedisBatchesBenchmark.evalsha localhost thrpt 50 52052.253 ± 1087.449 ops/s
RedisBatchesBenchmark.eval localhost thrpt 50 50806.715 ± 1220.019 ops/s
RedisBatchesBenchmark.evalshags localhost thrpt 50 47248.272 ± 1096.685 ops/s
RedisBatchesBenchmark.evalgs localhost thrpt 50 44633.113 ± 1829.829 ops/s
RedisBatchesBenchmark.naive localhost thrpt 50 35757.586 ± 1455.315 ops/s
RedisBatchesBenchmark.eval remote thrpt 50 4030.373 ± 19.535 ops/s
RedisBatchesBenchmark.async remote thrpt 50 4010.730 ± 19.527 ops/s
RedisBatchesBenchmark.async_flush remote thrpt 50 4004.914 ± 25.449 ops/s
RedisBatchesBenchmark.evalgs remote thrpt 50 3983.623 ± 31.027 ops/s
RedisBatchesBenchmark.evalshags remote thrpt 50 3978.253 ± 51.875 ops/s
RedisBatchesBenchmark.evalsha remote thrpt 50 3949.376 ± 52.273 ops/s
RedisBatchesBenchmark.naive remote thrpt 50 2015.643 ± 17.920 ops/s
Run Code Online (Sandbox Code Playgroud)
我们在这里看到什么?
MULTI因为它不能用于共享连接,并且应更改基准测试以包含它。这会增加更多的开销,所以不会这样做。