0.001Reids的5种数据结构
redis是一个开源的使用C语言编写的一个kv存储系统,是一个速度非常快的非关系远程内存数据库。它支持包括String、List、Set、Zset、hash五种数据结构。
通过哨兵(sentinel)和自动分区(Cuuster)的方式可以提高redis服务器的高可用性。
与关系型数据库相比,redis的请求命令不需要经过查询分析器或查询优化器进行处理,也避免了更新数据时引起随机读写,他直接读写内存中的数据,并且数据是按照一定的数据结构储存的。SO速度非常快。
字符串(String)
常用的操作:
set key values
get key
getset key value 将给定key的值设为value,并返回key的旧值(old value)
mget key1 [key2...]获取所有(一个或多个)给定key的值
setex key secondes value 将值value关联到key,并将key的过期时间设置为secondes(以秒为单位)
还有自增和自减操作。Redis的动态字符串由(SDS:Simple Dynamic String)实现:
定义SDS对象,此对象中包含三个属性:
1.len buf中已经占有的长度(表示此字符串的实际长度)
2.free buf中未使用的缓冲区长度
3.buf[] 实际保存字符串数据的地方
空间分配原则:当len小于IMB(1024*1024)时增加字符串分配空间大小为原来的2倍,当len大于等于1M时每次分配 额外多分配1M的空间。
特性:
二进制安全的
高效的计算字符串长度(时间复杂度为O(1))
高效的追加字符串操作
列表(List) ------------->有序储存
常用的操作:
存---LPUSH key value [value ...] 取--LRANGE key start stop lrange key start stop 获取列表指定范围内的元素 lindex key index 通过索引获取列表中的元素 lpush key value [value ...] 将一个或多个值插入到列表头部 lpush lpop rpush rpop等等操作命令,由ziplist和linkedlist实现。
列表对象使用ziplist编码:
列表对象保存的所有字符串元素的长度都小于64字节
列表对象保存的元素数量小于512个
当有任一条件 不满足时将会进行一次转码,使用linkedlist。
3.2之后的版本由quicklist实现,(注解:quicklist由ziplist双向链表组成)
哈希(Hash)
常用方法:
存--HMGET key field [field ...] 取--HMGET key field [field ...] M:表示能取多个值,many H:表示hash类型 hgetall key 获取哈表表中所有字段的值及字段 hexists key field 查看哈希表中,指定的字段是否存在,存在返回1,不存在(哈希表或指定字段不存在)返回0 hvals key 获取哈希表中所有值
可存储多个键值对映射,散列存储的既可以是字符串也可以是数字值。可以进行自增自减
Hash的两种实现:
第一种是ziplist,上面已经提到过。当存储的数据超过配置的阀值时就是转用hashtable的结构。(消耗性能)
第二种就是hashtable。这种结构的时间复杂度为O(1),但是会消耗比较多的内存空间。
集合(Set) ----------->无序
常用方法:
存--sadd key member [member ...] 取--SMEMBERS key scard key 获取集合的成员数 SINTER key1 [key2] 返回给定所有集合的交集 SISMEMBER key member 判断 member 元素是否是集合 key 的成员
redis的集合和列表都可以存储多个字符串,它们之间的不同在于,列表可以存储多个相同的字符串,而集合则通过使用散列表(hashtable)来保证自已存储的每个字符串都是各不相同的,redis中的集合是无序的。还可能存在另一种集合,那就是intset,它是用于存储整数的有序集合,里面存放同一类型的整数。
有序集合(Zset)
常用方法:
zadd:往集合中添加元素
zrem:删除集合中指定的元素
zrevrank:返回指定元素,在集合中的所对应的索引。
zrevrange:按集合顺序,从大到小进行显示
zcount:返回指定顺序范围内元素的个数,按元素顺序
有序集合和散列一样,都用于存储键值对:有序集合的键被称为成员(member),每个成员都是各不相同的。有序集合的值则被称为分值(score),分值必须为浮点数。有序集合是redis里面唯一一个既可以根据成员访问元素(这一点和散列一样),又可以根据分值以及分值的排列顺序访问元素的结构。
两种存储方式:
是ziplist结构。与hash中的ziplist类似,member和score顺序存放并按score的顺序排列
另一种是skiplist与dict的结合。
redis一般应用场景:
缓存会话(单点登录)
分布式锁,比如:使用setnx
各种排行榜或计数器
商品列表或用户基础数据列表等
使用list作为消息对列
秒杀,库存扣减等
五种类型的应用场景
String,redis对于KV的操作效率很高,可以直接用作计数器。例如,统计在线人数等等,另外string类型是二进制存储安全的,所以也可以使用它来存储图片,甚至是视频等。
hash,存放键值对,一般可以用来存某个对象的基本属性信息,例如,用户信息,商品信息等,另外,由于hash的大小在小于配置的大小的时候使用的是ziplist结构,比较节约内存,所以针对大量的数据存储可以考虑使用hash来分段存储来达到压缩数据量,节约内存的目的,例如,对于大批量的商品对应的图片地址名称。
list,列表类型,可以用于实现消息队列,也可以使用它提供的range命令,做分页查询功能。
set,集合,整数的有序列表可以直接使用set。可以用作某些去重功能,例如用户名不能重复等,另外,还可以对集合进行交集,并集操作,来查找某些元素的共同点
zset,有序集合,可以使用范围查找,排行榜功能或者topN功能。