redis使用-进阶
介绍:
基于内存的、key-value类型的、数据库 ;多种数据结构 ;
定期通过异步操作吧数据库数据flush到硬盘
性能:每秒可以处理超10W次读写请求
相关常用命令:
set k1 111
exist k1
del k1
ttl 返回键的剩余过期时间
当 key 不存在时,返回 -2 。
当 key 存在但没有设置剩余生存时间时,返回 -1 。
否则,以秒为单位,返回 key 的剩余生存时间。
expire k1 10 设置10S过期时间
type k1
lpush list1 "1" 插入到列表
数据类型:
1、string类型
实际可以是字符串或者数字
可以设置过期时间;计数incr k1;
应用场景:缓存或计数器
2、Hash类型 (散列类型)
设置:
hset user name zhansan
hset user age 28
取值:
hget user name
hget user age
使用场景
存储用户信息或商品信息
https://blog.****.net/qq422431474/article/details/108107202
我们简单举个实例来描述下Hash的应用场景,比如我们要存储一个用户信息对象数据,包含以下信息:
用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,如果用普通的key/value结构来存储,主要有以下2种存储方式:
第一种方式将用户ID作为查找key,把其他信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入CAS等复杂问题。
第二种方法是这个用户信息对象有多少成员就存成多少个key-value对儿,用用户ID+对应属性的名称作为唯一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,但是用户ID为重复存储,如果存在大量这样的数据,内存浪费还是非常可观的。也就是说,Key仍然是用户ID, value是一个Map,这个Map的key是成员的属性名,value是属性值,这样对数据的修改和存取都可以直接通过其内部Map的Key(Redis里称内部Map的key为field), 也就是通过 key(用户ID) + field(属性标签) 就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。很好的解决了问题。
3、List类型
目的:存储有序的字符串列表
结构:列表类型内部使用的是双向链表
操作:向列表两端添加元素push和弹出元素pop
命令:lpush rpush lrange-从右到左获取列表的所有元素
使用场景:商品列表、菜单列表
4、set类型
特点:不重复且没有顺序
命令:
sadd s1 a b c d
求交集sinter
求并集sunion
使用情景:
- 利用值的唯一性,和集合提供的,对两个集合间的数据进行交集、并集、差集运算的操作,来推荐好友和获取共同好友等
- 利用值的唯一性,可以统计访问网站的所有独立 IP
5、zset
https://www.cnblogs.com/wuyizuokan/p/11108417.html
介绍:有序集合;每个元素都关联一个分数;
能够获得分数最高或最低的前N个元素、获取指定分数范围的元素
底层:
所以ZSet采用了一种跳跃表的实现。这个实现有点类似于Kafka存储消息是使用的稀疏索引
命令:
添加:zadd iphone 100 mi 200 huawei 200
查看所有元素,按照score顺序排序:zrange phone 0 -1
查看所有元素,按照score逆序排序: zrevrange phone 0 -1
获取指定value的分数, zscore phone mi value
获取指定value的排名,zrank phone mi
使用场景:
排行榜:
经常浏览技术社区的话,应该对 “1小时最热门” 这类榜单不陌生。如何实现呢?
我们以当前小时的时间戳作为 zset 的 key,把贴子ID 作为 member ,点击数评论数等作为 score,当 score 发生变化时更新 score。利用
ZREVRANGE
或者ZRANGE
查到对应数量的记录。使用场景:适合处理点击数、访问量之类,处理发帖回复这种还需要考虑,帖子审核不通过的情况
延迟队列:
zset 会按 score 进行排序,如果 score 代表想要执行时间的时间戳。在某个时间将它插入 zset 集合中,它变会按照时间戳大小进行排序,也就是对执行时间前后进行排序。
起一个死循环线程不断地进行取第一个 key 值,如果当前时间戳大于等于该 key值的 score 就将它取出来进行消费删除,可以达到延时执行的目的。
问题:没有ack机制,当消费失败的情况下队列如何处理 ;
Redis内存机制:
介绍:当redis的内存达到一定阈值maxmemory时,会自动调用内存优化策略来维护内存的大小
内存优化策略:volatile -- 设定失效时间 lru--最少使用的
volatile-lru: 在设定过失效时间的数据中,查找最近最少使用的数据进行删除
allkey-lru: 在redis中的所有的数据删除最近最少使用的数据
volatile-random: 在设定了超时时间的数据中随机进行删除操作
allkeys-random:所有的key都会进行随机删除操作
redis的持久化机制:
介绍:
redis中的数据都在内存中,如果发生了断点或者宕机 。这时内容的数据都会清空.redis如何保证内存数据不丢失(尽可能不丢失) 。redis内部有2中缓存持久化的策略.分别是RDB模式和AOF模式
RDB:
(1)redis默认的持久化方式;定期将redis内存数据持久化到RDB文件中;
(2)当reids重新启动时,首先会检查RDB的持久化文件,将内存数据进行恢复(恢复现场)
(3)主动备份:
save 自动的创建一个线程用来实现数据备份;
该线程启动后,会造成redis其他线程的阻塞.只有当该线程持久化完毕后,其他线程才会执行
bgsave
会开启后台线程进行数据备份.这时的数据备份不是马上执行.
而是等待线程抽空自己执行.不会造成线程的阻塞.但是该操作有延时
AOF:
当AOF持久化策略采用 always时,表示实时持久化,只要有set操作就会进行持久化.性能较低.
当AOF持久化文件采用everysec时,表示每秒进行一次数据备份.性能比always要高很多.但是不如RDB性能高
当AOF持久化文件采用 no 时,表示持久化的时间交给操作系统自己调用.由操作系统自己决定.
比较:
如果对于redis中的数据完整性要求不高则采用高效的RDB模式进行持久化操作.
如果对数据完整性有较高的要求采用AOF的方式(建议采用everysec)
redis客户端:
redis desktop manager
redis集群:
redis集群使用场景:之前做的报表系统,由于数据量巨大、sql查询较慢,所以使用redis来提升查询速度(将查询结果存储在redis中),这样导致redis中存储的数据量巨大,此时一台redis服务器已经承受不住了。为了提升redis内存和高可用,所以要搭建redis集群
单台redis的缺点:单台reids可能出现宕机现象;单台redis内存受限
//TODO 后续更新
redis管理序列化对象://todo