Redis常用的数据结构
- 字符串----String
- 哈希---hash
- 列表----list
- 集合---set
- 有序集合----zset
当然还有数据结构:BitMap,HighLogLog,GEO
1. String结构常用的操作
字符串常用操作
- set key value 存入字符串键值对
- mset key value [key value...] ----批量存储字符串键值对
- setnx(set if not exit),值不存在则设置值
- mget -----批量获取字符串键值
- get key -----获取一个字符串键值
- del key -----删除一个键值
- expire key seconds -----设置一个键的过期时间
原子加减
- incr key --- 将key中存储的数字值加1
- deccr key ----- 将key中存储的数字值减1
- increby key increment ---- 将key中所存储的值 加上 increment自定义的值
- decreby key decrement ---- 将key中所存储的值减去相应的值
redis的单线程是基于他的命令的,比如get,set,mset,mget命令等,因此在执行一条命令的时候时间不宜过长,否则在高并发场景下会影响它的性能。hash结构的大key就是会出现这样的问题,因此在开发的过程中尽量避免hash结构的大key。 大key(bigkey)指的是这个key对应得值很大,导致在对这个key查询过程中,时间太长了。这里涉及线程模型和redis的优化实践。
分段存储hash结构
hash结构应用场景
- 电商购物车
hash结构---电商购物车
a. 用户id为key
b.商品id为field
c.商品数量为value
- 对购物车的操作
- 添加商品 -->hset cart:1001 10088 1:表示对对1001这个购物车的10088这件商品添加1件进购物车
- 增加购物车商品中的数量--->hincrby cart:1001 10088 1 表示在购物车1001中的10088这个商品增加一件,此时购物车1001中10088这件商品有两件。
- 获取购物车中商品的总数:hlen cart:1001 结果为3
- 删除购物车中10088这件商品:hdel cart:1001 10088
- 获取购物车所有的商品:hgetall cart :1001
redis集群希望数据平均分配: 使用hash结构的话容易导致数据分配倾斜,一个hash结构key中存放大量的数据,是有办法去解决的,数据分片。Redis集群
list数据结构
可以实现实现常用的数据结构
- 栈:lpush + lpop-----左近左出(与jdk中栈的区别是,可以在分布式环境下使用)
- 队列:lpush + rpop----左近右边出
- 阻塞队列(Blocking MQ):lpush + brpop
BitMap(String),GEO都是5种常用的数据结构的扩展
-
应用场景
-
微博微信公众号消息流,新浪微博重度依赖Redis
后发消息的展示在最前面。
set数据结构
boardmix.cn/app/share/C… 点击链接加入boardmix中的文件「Redis常用数据结构」
zset有序结合结构
往有序集合key中加入带分值元素 ZADD key score member [[score member]...]
集合倒叙排序取前面10条记录 ZREVRANGE hotNews:ID 0 9 withscores
Redis的单线程和高性能
- Redis是单线程的么? redis的单线程是针对客户端发起的命令的操作-----执行命令的操作是由一个线程来执行的,其后端的持久化,过期异步删除,集群数据的同步都是由redis服务端其他线程去操作的。
Redis的单机并发是很高的。
-
Redis单线程为什么还这么快
- 基于内存,所有的运算都是基于内存的运算----核心
- Redis是单线程的,避免了多线程之间的切换所造成的cpu消耗
- 基于IO多路复用
- Redis的数据结构设计的就是以空间换时间。
-
Redis单线程如何处理那么多的并发客户端连接?
RedisIo多路复用:利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器中,事件分派器将事件分发给事件处理器。
客户端发送过来的命令Redis全部接收放到Redis中的一个队列里面去,后端通过事件监听器,基于NIO可以一次性响应多个请求。由事件分派器一次性分派多个命令,在内存中还是按照顺序执行命令。