关于Redis性能调优方面的注意事项

561 阅读3分钟

    习惯了关系数据库的用户在刚开始使用Redis 的时候,通常会因为Redis带来的上百倍的性能提升而感到欣喜若狂,却没有认识到Redis 的性能实际上还可以做进一步的提高。虽然上一节介绍的非事务型流水线可以尽可能地减少应用程序和Redis之间的通信往返次数,但是对于一个已经存在的应用程序,我们应该如何判断这个程序能否被优化呢?我们又应该如何对它进行优化呢? 

      要对Redis 的性能进行优化,用户首先需要弄清楚各种类型的Redis命令到底能跑多块,而这一点可以通过调用Redis 附带的性能测试程序redis-benchmark来得知,下面代码展示一个相应的例子。如果有兴趣的话,大家也可以试着用 redis-benchmark 来了解 Redis在自己服务器上的各种性能特征。

    redis-benchmark 的运行结果展示了一些常用 Redis 命令在 1 秒内可以执行的次数。如果用户在不给定任何参数的情况下运行 redis-benchmark,那么 redis-benchmark 将使用50 个客户端来进行性能测试,但是为了在 redis-benchmark 和我们自己的客户端之间进行性能对比,让 redis-benchmark 只使用一个客户端要比使用多个客户端更方便一些。

       在考察 redis-benchmark 的输出结果时,切记不要将输出结果看作是应用程序的实际性能,这是因为 redis-benchmark 不会处理执行命令所获得的命令回复,所以它节约了大量用于对命令回复进行语法分析的时间。在一般情况下,对于只使用单个客户端的 redis-benchmark 来说,根据被调用命令的复杂度,一个不使用流水线的 Python客户端的性能大概只有 redis-benchmark 所示性能的 50%~60%。 

        另一方面,如果你发现自己客户端的性能只有redis-benchmark所示性能的25%至30%,或者客户端向你返回了"Cannot assign requestedadres"(无法分配指定的地址)错误,那么你可能是不小心在每次发送命令时都创建了新的连接。 

        下面列出了只使用单个客户端的 redis-benchmark与Python客户端之间的性能对比结果,并介绍了一些常见的造成客户端性能低下或者出错的原因。

     

         上面 列出的性能问题以及问题的解决方法都非常简短,但绝大部分常见的性能问题都是由表格中列出的原因引起的(另一个引起性能问题的原因是以不正确的方式使用 Redis 的数据结构)。如果大家遇到了难以解决的性能问题,或者遇到了上面没有介绍的性能问题,那么可以直接找兔哥寻求帮助。

         大部分Redis 客户端库都提供了某种级别的内置连接池(connection pool)。以Python 的Redis客户端为例,对于每个Redis服务器,用户只需要创建一个redis.Redis()对象,该对象就会按需创建连接、重用已有的连接并关闭超时的连接(在使用多个数据库的情况下,即使客户端只连接了一个Redis 服务器,它也需要为每一个被使用的数据库创建一个连接),并且Python客户端的连接池还可以安全地应用于多线程环境和多进程环境