Redis(数据类型、线程模型、过期策略、持久化)

本文深入探讨Redis的数据类型(string, hash, list, set, sortedset)及其应用场景,揭秘单线程模型如何高效运作,包括文件事件处理器和IO多路复用。此外,解析Redis的过期策略和持久化选项,如RDB与AOF的选择指南。
摘要由CSDN通过智能技术生成

目录

Redis数据类型

Redis单线程模型

Redis过期策略

Redis持久化


Redis数据类型

string
	set key val
	
hash
	hset person name bingo
	hset person age 20
	hset person id 1
	hget person name
	person = {
		"name": "bingo",
		"age": 20,
		"id": 1
	}
	
list
	list 是有序列表,这个可以玩儿出很多花样。

	比如可以通过 list 存储一些列表型的数据结构,类似粉丝列表、文章的评论列表之类的东西。

	比如可以通过 lrange 命令,读取某个闭区间内的元素,可以基于 list 实现分页查询,这个是很棒的一个功能,基于 redis 实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西,性能高,就一页一页走。

	# 0开始位置,-1结束位置,结束位置为-1时,表示列表的最后一个位置,即查看所有。
	lrange mylist 0 -1
	比如可以搞个简单的消息队列,从 list 头怼进去,从 list 尾巴那里弄出来。

	lpush mylist 1
	lpush mylist 2
	lpush mylist 3 4 5

	# 1
	rpop mylist
	
set
	set 是无序集合,自动去重。

	直接基于 set 将系统里需要去重的数据扔进去,自动就给去重了,如果你需要对一些数据进行快速的全局去重,你当然也可以基于 jvm 内存里的 HashSet 进行去重,但是如果你的某个系统部署在多台机器上呢?得基于 redis 进行全局的 set 去重。

	可以基于 set 玩儿交集、并集、差集的操作,比如交集吧,可以把两个人的粉丝列表整一个交集,看看俩人的共同好友是谁?对吧。

	把两个大 V 的粉丝都放在两个 set 中,对两个 set 做交集。

	#-------操作一个set-------
	# 添加元素
	sadd mySet 1

	# 查看全部元素
	smembers mySet

	# 判断是否包含某个值
	sismember mySet 3

	# 删除某个/些元素
	srem mySet 1
	srem mySet 2 4

	# 查看元素个数
	scard mySet

	# 随机删除一个元素
	spop mySet

	#-------操作多个set-------
	# 将一个set的元素移动到另外一个set
	smove yourSet mySet 2

	# 求两set的交集
	sinter yourSet mySet

	# 求两set的并集
	sunion yourSet mySet

	# 求在yourSet中而不在mySet中的元素
	sdiff yourSet mySet

sorted set
	sorted set 是排序的 set,去重但可以排序,写进去的时候给一个分数,自动根据分数排序。

	zadd board 85 zhangsan
	zadd board 72 lisi
	zadd board 96 wangwu
	zadd board 63 zhaoliu

	# 获取排名前三的用户(默认是升序,所以需要 rev 改为降序)
	zrevrange board 0 3

	# 获取某用户的排名
	zrank board zhaoliu

Redis单线程模型

文件事件处理器file event handler
	单线程
	采用IO多路复用机制同时监听多个socket,将产生事件的socket压入内存队列中,事件分派器根据 socket 上的事件类型来选择对应的事件处理器进行处理
	多个 socket、IO 多路复用、文件事件分派器、事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)
	要明白,通信是通过 socket 来完成的,不懂的同学可以先去看一看 socket 网络编程。

	首先,redis 服务端进程初始化的时候,会将 server socket 的 AE_READABLE 事件与连接应答处理器关联。

	客户端 socket01 向 redis 进程的 server socket 请求建立连接,此时 server socket 会产生一个 AE_READABLE 事件,IO 多路复用程序监听到 server socket 产生的事件后,将该 socket 压入队列中。文件事件分派器从队列中获取 socket,交给连接应答处理器。连接应答处理器会创建一个能与客户端通信的 socket01,并将该 socket01 的 AE_READABLE 事件与命令请求处理器关联。

	假设此时客户端发送了一个 set key value 请求,此时 redis 中的 socket01 会产生 AE_READABLE 事件,IO 多路复用程序将 socket01 压入队列,此时事件分派器从队列中获取到 socket01 产生的 AE_READABLE 事件,由于前面 socket01 的 AE_READABLE 事件已经与命令请求处理器关联,因此事件分派器将事件交给命令请求处理器来处理。命令请求处理器读取 socket01 的 key value 并在自己内存中完成 key value 的设置。操作完成后,它会将 socket01 的 AE_WRITABLE 事件与命令回复处理器关联。

	如果此时客户端准备好接收返回结果了,那么 redis 中的 socket01 会产生一个 AE_WRITABLE 事件,同样压入队列中,事件分派器找到相关联的命令回复处理器,由命令回复处理器对 socket01 输入本次操作的一个结果,比如 ok,之后解除 socket01 的 AE_WRITABLE 
为啥 redis 单线程模型也能效率这么高
	纯内存
	IO 多路复用
	单线程避免了频繁的上下文切换

Redis过期策略

//定期删除
//惰性删除
//内存淘汰机制
	allkeys-lru		键空间中移除最少使用

//手写一个 LRU 算法
class LRUCache<K, V> extends LinkedHashMap<K, V> {
	private final int CACHE_SIZE;

	/**
	 * 传递进来最多能缓存多少数据
	 *
	 * @param cacheSize 缓存大小
	 */
	public LRUCache(int cacheSize) {
		// true 表示让 linkedHashMap 按照访问顺序来进行排序,最近访问的放在头部,最老访问的放在尾部。
		super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true);
		CACHE_SIZE = cacheSize;
	}

	@Override
	protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
		// 当 map中的数据量大于指定的缓存个数的时候,就自动删除最老的数据。
		return size() > CACHE_SIZE;
	}
}

Redis持久化

RDB
	周期性持久化
	适合做冷备
	每隔5分钟

AOF
	每条命令都写日志
	数据更完整
	每隔1秒
	适合做灾难性的误删除的紧急恢复
		比如某人不小心用 flushall 命令清空了所有数据,只要这个时候后台 rewrite 还没有发生,那么就可以立即拷贝 AOF 文件,将最后一条 flushall 命令给删了,
		然后再将该 AOF 文件放回去,就可以通过恢复机制,自动恢复所有数据。

如何选择
	同时开启两种持久化方式
	用 AOF 来保证数据不丢失,作为数据恢复的第一选择
	用 RDB 来做不同程度的冷备,在 AOF 文件都丢失或损坏不可用的时候,还可以使用 RDB 来进行快速的数据恢复

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值