Redis是一种高性能高并发KV存储,在实际应用中常常用于缓存、分布式锁、消息队列等常见。Redis的性能为什么这么快呢,一方面是由于它的线程模型:多路复用+异步事件响应,另一方面则是由于它的所有逻辑操作都在内存中完成,并且Redis的作者在底层使用了很多巧妙的数据结构,使得Redis的数据结构丰富且高效。
今天这篇笔记是Redis的数据类型实践,底层的原理我们放在下一篇文章研究。
基础数据类型
String(字符串类型)
字符串类型是Redis中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据。字符串类型是其他四种数据结构(List、Hash、Sorted Set、Set)的基础,其他数据类型和字符串类型的差别来说只是组织字符串的形式不同。例如:列表类型是列表的形式组织字符串,而集合类型是以集合的形式组织字符串。
字符串类型的操作包括:set、get、incr。可以看出,incr命令操作一个非整数类型的key时,Redis会提示错误。
Hash(散列类型)
Redis采用字典结构(全局Hash表)存储KV数据,而散列类型的键值也是一种字典结构,它存储了字段和字段值的映射,但是字段值只能是字符串类型,不能是其他数据类型。也就是说,Redis的Hash、List、Sorted Set、Set的元素都不支持数据类型的嵌套。
Hash适合存储对象数据,并能够操作对象中的单个字段的值。Hash数据类型的常用操作:hset、hget、hgetall、hexists、hsetnx、hincrby、hdel。
List(列表类型)
列表类型可以存储一个有序的字符串列表,常用的操作是向队列两端添加元素,或者获得列表的某一个片段。列表类型的内部是使用双向列表实现的,所以向列表两端添加元素的时间复杂度是O(1),获取越接近两端的元素速度就越快。
列表类型的使用常见包括:社交网站的新鲜事使用列表类型存储,即使新鲜事的总数达到几万个,获取前10个也是极快的;列表类型还可以用于消息队列,在大促活动时候,为了应对流量洪峰,可以将请求缓存在List队列中,后续再慢慢消费进行底层的数据库操作。
List的常见命令包括:lpush、rpush、lpop、rpop、llen、lrange、lrem
Set(集合)
集合类型常用于存储一组唯一不重复的字符串,例如标签。集合类型的常用操作是向集合中加入或删除元素,判断某个元素是否存在等,集合之间还可以进行并集、交集和差集等操作。
Sorted Set(有序集合)
有序集合类型和集合类型的区别就是它可以对集合中的元素进行排序,每个元素都关联了一个分数。有序集合的常用操作,除了集合类型的那些操作外,可以获得分数最高或最低的前N个元素,获得指定分数范围内的元素等。
有序集合和列表类型一样,都是有序的,但是列表类型无法保障元素的唯一性。有序集合底层是使用跳表实现的,因此做范围查询的时间复杂度也很快,而列表类型在做范围查询的时候时间复杂度则比较慢。
高级数据类型
HyperLogLog
HyperLogLog是一种用于统计基数的数据集合类型,它最大的优势在于:当集合类型的数量非常多的时候,它计算基数所需要的空间是固定的,而且还很小。在统计网页的UV这种场景下,在UV非常高的时候就适合用HyperLogLog这种数据类型。
HyperLogLog的统计规则是基于概率完成的,它给出的统计结果是有一定误差的,如果需要精确统计结果的话,最好还是使用Set或Hash类型。
Bitmap
Bitmap比较适合用于签到统计场景,在这种场景下,每个用户一天的签到用1个bit就可以表示,一年的签到也只需要365bit,不需要用太复杂的集合类型。在记录海量数据的时候,Bitmap可以有效节省内存空间。
Bitmap本身是用String类型作为底层数据结构实现的一种统计二值状态的数据类型。String类型是会保存为二值状态的字节数组,可以将Bitmap看做是一种bit数组。
Bitmap提供了getbit和setbit操作,使用一个偏移量offset对bit数组的某一个bit进行读写。
GEO
GEO数据类型适合用于基于LBS的应用,LBS应用访问的数据是和人或物关联的一组经纬度信息,而且需要能够查询相邻的经纬度范围。
GEO底层是基于Sort Set实现的,区别是它是将经纬度信息按照GeoHash编码算法将经纬度信息转化成Sorted Set中的score。在Sorted Set中查到的相邻的编码值,在实际的地理空间上也是相邻的方格,这就可以实现LBS应用“搜索附近的人或物”的功能了。
在使用GEO类型时,常用的操作有两个
GEOADD:用于将一组经纬度信息和相对应的ID记录在GEO类型集合中;
GEORADIUS:会根据输入的经纬度位置,查找以这个经纬度为中心的一定范围内的其他元素。
参考资料
http://c.biancheng.net/redis/
redis试验:https://try.redis.io/
redis命令手册:https://redis.com.cn/commands.html
《Redis入门指南》
《Redis核心技术与实践》