Hellow! 想必大家多多少少都听过我Redis的大名,我最常被标注的标签 :缓存 、快、高性能、低延迟 ,其实我也不想被贴上如此多的标签,能力越大背负就越多,日后的路希望与各位共勉。
我是一个开源的内存数据结构存储系统,我可以存储多种数据结构,例如,字符串、散列表、列表、集合、有序集合等。至于我如何做到好评如潮的,后面我来给大家一 一 介绍,剖析自己。
是Redis中最基本的数据结构
使用场景:
缓存数据:
SET key value //存入字符串键值对 MSET key value [key value ...] //批量存储字符串键值对 SETNX key value //存入一个不存在的字符串键值对 GET key //获取一个字符串键值 MGET key [key ...] //批量获取字符串键值 DEL key [key ...] //删除一个键 EXPIRE key seconds //设置一个键的过期时间(秒)
计数器
INCR key //将key中储存的数字值加1 DECR key //将key中储存的数字值减1 INCRBY key increment //将key所储存的值加上increment DECRBY key decrement //将key所储存的值减去decrement
分布式锁
SETNX product:10001 true //返回1代表获取锁成功 SETNX product:10001 true //返回0代表获取锁失败 DEL product:10001 //执行完业务释放锁 SET product:10001 true ex 10 nx //防止程序意外终止导致死锁
集合是一个无序集合,通过哈希实现,可快速添加、删除和查找
存储对象信息
HMSET user 1:name zhangsan 1:age 18 HMSET user 2:name lisi 1:age 19 HMGET user 1:name 1:age
存储结果“”
缺点:
不适合存储大量数据,因为所有数据都在一个Key下
过期功能不能使用在field上,只能用在Key上
列表是简单的字符串列表,支持从两端插入和删除,适用消息队列等场景
消息队列
Blocking MQ(阻塞队列)= LPUSH + BRPOP Queue(队列)= LPUSH + RPOP # 从列表左侧插入元素 LPUSH tasks "process_video" # 从列表右侧弹出元素 BPOP tasks
时间线
LPUSH message:{用户id} 1 LPUSH message:{用户id} 2 LPUSH message:{用户id} 3 LPUSH message:{用户id} 4 LRANGE message:{用户id} 0 3
缺点:
元素较多时,访问中间元素时间为O(n)
列表尾部添加和移除很快,头部操作慢
集合是一个无序集合,它通过哈希表实现,具有快速添加、删除、和查找操作的特点
点赞收藏
1) 点赞 SADD like:{消息ID} {用户ID} 2) 取消点赞 SREM like:{消息ID} {用户ID} 3) 检查用户是否点过赞 SISMEMBER like:{消息ID} {用户ID} 4) 获取点赞的用户列表 SMEMBERS like:{消息ID} 5) 获取点赞用户数 SCARD like:{消息ID}
交集并集等
SINTER set1 set2 set3 { c } SUNION set1 set2 set3 { a,b,c,d,e } SDIFF set1 set2 set3 { a }
优点:
元素唯一
集合间操作
缺点:
不支持排序
不能直接获取集合中的元素
有序集合是将集合和散列表结合起来,给每个元素设置一个分数,然后根据分数排序
排行榜
//展示当日排行前十 ZREVRANGE hotNews:20190819 0 9 WITHSCORES
因为Redis所有数据都存储在内存中,所有的运算都是内存级别的运算,并且我是单线程,避免了多线程导致的上下文切换带来的性能损耗。同样的因为单线程,所以在使用的时候要注意,如果执行一些耗时的指令,Redis可能造成卡顿~
Redis 的单线程主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。Redis有也有多线程的功能,比如持久化、异步删除、集群数据同步等
Redis的IO多路复用:redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器。