目录
Redis的一些使用场景
存储示例
使用字符串类型
使用json字符串类型
使用哈希类型
Redis的一些常用场景,有数据排序查询、session存储,缓存等,数据排序前面的日志中有体现,如果我们想要维护一个歌曲热度排名名单,可以在Redis中使用有序集合,通过ZADD命名添加对象到一个有序集合中,之后使用ZREVRANGE命令或ZRANGE命令将集合里的元素按权重降序或升序输出。session通常存储在服务器之外的外部内存中,Redis作为基于内存的轻量级键值数据库,用来存放session十分合适,Redis在内存里提供了原生的数据结构实现(string、list、hash、set等),并且提供了对应的API,实现高效率的数据处理,对比起关系型数据库,优势在于访问延迟很低。此外还有一个重要的场景是Redis可以作为关系型数据库的缓存,以次来提高数据库查询的效率,例如,对关系型数据库查询较缓慢时,我们可以将一些查询结果缓存到Redis中,下一次查询时先去Redis中查找是否有记录,如果没有再向关系数据库中查询。同样的,在向关系数据库中插入记录时,也可以先将其插入到Redis中,减轻数据库访问的压力。但是对于Redis作为关系数据库缓存的场景中,有一点需要注意,还记得前面日志说到Redis事务时,对比关系数据库事务,它们两者有什么区别吗?一大区别是,Redis事务并不是完全符合原子性的,Redis事务并不支持回滚,详细的这里不详述,大家可以看我之前那篇日志《列表/集合排序与Redis事务》。所以在对于原子性,一致性等有硬性要求的场景下,就不要用Redis了。虽然Redis比起关系数据库在访问速度上有不错的提升,但若想进一步提高Redis效率,还是有方法的,在不同场景中,针对使用不同的数据类型,可以减低内存消耗,这篇日志就来总结下Redis使用过程中的其中一个优化方式,使用不同的数据类型存储数据。
首先来看一个存储用户信息的例子,用不同的数据类型保存后看内存消耗比较。假设我们在Redis中导入存储大量的用户信息,一个user包含姓名name和性别sex,希望以尽量节省的内存消耗存储,怎么做?通常来说,存储用户信息使用字符串形式很适合,来试试,在存储之前先看看我们的Redis中没用内存使用时的内存消耗情况:
如上图所示,使用keys *命令查看Redis中列表或集合都为空,使用命令INFO MEMORY查看当前的内存消耗时807.99k。接着我们写一个bash脚本文件,生成用户信息并保存到Redis中。
第一种方式首先我们使用字符串类型来存储用户数据:
脚本文件中每一条用户信息包含name、sex和生成时间time。循环一万次意味着我们要将一万条信息保存到Redis中,脚本编写完,保存,接着使用命令bash执行脚本,得到string.data数据文件,我们再通过cat string.data | redis-cli –pipe命令,即使用管道方式将数据导入到Redis中去,最后我们再回到Redis中用INFO MEMORY命令来看看当前的内存消耗:
可以看到,如果使用字符串类型,内存消耗接近4M。这是最常想到的第一种方式,使用字符串存储,如果我们想要优化内存消耗,可以换一种数据类型,例如使用JSON字符串。
json字符串是一种格式,基于文本,优点是较轻量,对比起string类型字符串用来存储数据是一种优化,同样的我们编写一个脚本生产用户信息并导入到Redis中:
接着使用命令bash执行脚本,得到json.data数据文件,再通过cat json.data | redis-cli –pipe命令以管道方式将数据导入到Redis中,最后查看下内存消耗:
可以看到,Redis内存使用从原来的4.26M降到了2.40M,优化了接近一半的内存消耗,所以说对于同样的(例子中每条用户数据大小大致相同)数据使用不同的数据类型存储,可以节省出很可观的空间。除了json字符串类型外,还有没有其他的数据类型?有的,往下看。
用户信息还可以尝试着用哈希类型存储,因为hash类型对比string类型更节约内存,尤其当key键的创建越来越多的时候,Redis对大量键的管理(需要使用一些数据结构来维护键)消耗的内存就越多,string类型对比起hash类型的劣势就越明显。同样的我们写个脚本验证一下:
使用hash类型来存储我们生成的用户信息,执行脚本得到hash.data数据文件,再通过cat hash.data | redis-cli –pipe命令将数据导入到Redis中,查看下内存消耗:
可以看到,Redis内存使用为2.53M,比json字符串类型多一点点,比string字符串类型有很大的优化,