OpenResty 中的 Redis 使用技巧

前言

Redis 是非常流行的 NoSQL 数据库之一,因其高效、稳定、开源、数据结构丰富,深受业内钦赖。很幸运,OpenResty 也内置了对 Redis 的支持。

在使用OpenResty的过程中,Redis一直是主力存储方式之一。虽然OpenResty内置了Redis驱动,但在实际项目中,对其进行进一步的封装,能更方便的使用和管理。

在这个过程中,遇到了很多需要注意的点,也积累了一些技巧和经验,在此总结一下。

技巧

单例模式

单例模式是对数据连接或数据查询工具类的常用处理模式。保持数据连接的单例好处很多,最重要的一点是确保了同一连接的复用,不会被重复打开浪费资源,也方便了连接的管理和状态维护。

在OpenResty中,可以通过把resty.redis:new()产生的对象保存到ngx.ctx中实现单例。同一请求可以通过ngx.ctx共享已打开的连接。

连接池

很多高级语言,例如Java、C++,都支持连接池特性。在使用完数据连接后,将连接归还给连接池,而不是关闭连接。下次连接时,会尝试复用连接池中的连接。在高并发下,能大大减少建立和断开连接的次数,从而大大的节省系统资源。

OpenResty的cosocket也支持连接池特性,而基于cosocket的MySQL和Redis驱动也顺理成章的支持了连接池特性。

在OpenResty中,在需要关闭连接时,使用client:set_keepalive(TIMEOUT, POOL_SIZE)代替client:close(),即可激活连接池特性。

尽量使用 Unix 套接字

OpenResty内置的Redis驱动连接Redis服务器有两种方式,一种是使用 IP 和端口,一种是使用 Unix 套接字。

如果Redis服务器和OpenResty服务在同一物理服务器上,则应优先使用 Unix 套接字模式连接。经过实际测试,使用 Unix 套接字模式相较于使用 IP 端口模式,速度能够提升10% ~ 15%。

数据隔离

Redis经常被用于数据缓存,在一个项目中,需要缓存的数据种类很多。几十种甚至上百种,都是现实中会遇到的情况。

Redis在没有调用select命令时,会默认将数据存储到dbindex 0的数据库。显然这样对缓存管理是很不利的。

想象一下这样一个场景,用户表因为一些原因需要进行批量更新,这时为了缓存的一致性,我们需要清理用户数据缓存。如果所有的缓存都混杂在一起,这显然是个令人头疼的任务。

所以,请将不同种类的数据,存储在不同的dbindex中,这样不管是查询还是管理,都会很方便,我们可以毫不费力的清除某一类数据,而不影响其他数据。

缓存数据和非缓存数据更是要隔离开来,这样才不会在后续的维护工作中给自己带来麻烦。

当然,这里需要一个技巧,否则每次查询之前都需要执行一次select命令,这可不是什么好主意。我们可以利用Redis中的pipeline特性,将select和我们要执行的命令打包在一起一次发送。

编码存储

默认情况下,Redis只能存储number、string、bool,而不能存储table,这显然不符合我们的预期。

这也很容易解决,对table进行编码,变成string自然就可以存储了。当然,为了兼容性,我们需要对所有存进去和取出来的值进行判断,以确定是不是需要编码解码,这会带来一些额外的性能消耗。

但可以直接保存table实在是一件很美妙的事,付出一些额外的代价也是很值得的。

关于编码方式,拥有的选择实在不多,考虑到cjson是内置模块,且json可读性较高,虽然编码效率并不尽人意,但是我还是选择了使用json来编码。

原文地址:http://zivn.me/2016/03/21/redis-tips-in-openresty/

你可能感兴趣的:(OpenResty 中的 Redis 使用技巧)