Redis 实战 —— 07. 复制、处理故障、事务及性能优化 (2)

在某些情况下提升性能。利用事务一次性发送多个命令,然后等待所有回复出现实现流水线 (pipeline)。通过减少客户端与 Redis 服务器之间的网络通信次数来提升 Redis 在执行多个命令时的性能。

关系数据库事务与 Redis 事务的区别: P76

关系数据库:先向数据库服务器发送 BEGIN ,然后执行各个相互一致 (consistent) 的读写操作,最后可以选择发送 COMMIT 来确认之前的修改,或者发送 ROLLBACK 来放弃之前的修改。

Redis :以特殊命令 MULTI 开始,然后传入多个命令,最后以 EXEC 结束,并依次执行传入的命令。Redis 事务不能以一致的形式读取数据,使得某一类型的问题难以解决,且无法实现二阶段提交。

通过使用 WATCH, MULTI/EXEC, UNWATCH/DISCARD 等命令,程序可以在执行某些重要操作时,通过确保自己正在使用的数据没有发生变化来避免出错。 P78

WATCH: 使用 WATCh 对键进行监视之后,直到用户执行 EXEC 的这段时间里面,如果有其他客户端抢先对任何被监视的键进行了替换、更新或删除等操作,那么当用户尝试执行 EXEC 时,事务将失败并返回一个错误。(之后用户可选择重试事务或者放弃事务)

UNWATCH: 可以在 WATCH 执行之后、 MULTI 执行之前对连接进行重置 (reset)

DISCARD: 可以在 MULTI 执行之后、 EXEC 执行之前对连接进行重置,即取消 WATCH 并清空所有已入队命令

为什么 Redis 没有实现典型的加锁功能? P82

加锁是悲观锁,持有锁的客户端运行越慢,等待解锁的客户端被阻塞的时间越长

WATCH 是乐观锁,客户端不必等待取得锁,只需要在事务执行失败时重试即可,乐观锁可以提高并发能力

非事务型流水线 (non-transactional pipeline)

对于无需事务的大量操作可以使用非事务型流水线,可以避免事务消耗资源。

Python 中通过修改入参即可将事务改为非事务型流水线,而 Go 中根据具体框架的不同,可能需要手动封装流水线的处理逻辑。

性能优化

要对 Redis 的性能进行优化,首先需要弄清楚各种类型的 Redis 命令能跑多块,而这一点可以通过调用 Redis 附带的性能测试程序 redis-benchmark 得知。 P85

切记不要将输出结果看作是应用程序的实际性能,因为 redis-benchmark 不会处理执行命令所获得的命令回复,所以它节约了大量用于对命令回复进行语法分析的时间。 P86

可能影响性能的原因 P86

未使用流水线:可视情况适当使用流水线

对于每个命令或每组命令都创建了新的连接:使用连接池重用 Redis 连接

Redis 的数据结构或命令不合理(value 非常大,使用 keys, hgetall 等):优化数据结构和命令

本文首发于公众号:满赋诸机(点击查看原文) 开源在 GitHub :reading-notes/redis-in-action

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzjwj.html