redis了解与介绍
https://blog.csdn.net/weixin_44981707/article/details/115610686(redis详解博客原文地址)
1.redis的常见数据类型及应用场景?
数据类型 |
描述 |
应用场景 |
字符串(Strings)
|
最简单的键值对数据类型,值可以是字符串、整数或浮点数。 |
缓存热点数据,如首页新闻、热门商品列表等。 存储简单的数据,如用户的用户名、密码等。 作为计数器使用,如网站访问次数、在线用户数量。 实现分布式锁机制。 存储全局唯一ID,利用原子性操作如INCR或INCRBY。 |
哈希表(Hashes)
|
一个键值对的集合,每个键值对有自己的字段名和值。 |
存储复杂对象,如用户详情,其中包含多个属性。 用于实时统计,如用户行为分析,可以按用户ID存储多个行为事件。
|
列表(Lists)
|
一个有序的字符串集合,可以从头部或尾部插入或移除元素。
|
消息队列,如生产者消费者模型。 实现简单的任务队列或待办事项列表。 记录最近操作的历史记录,如最近浏览的商品列表。 |
集合(Sets)
|
一个无序的、不重复的字符串集合。 |
存储多个不重复的元素,如用户好友列表。 对多个集合执行交集、并集、差集操作,如找出两个用户共同的好友。 实现推荐系统,找出用户可能感兴趣的商品集合。 |
有序集合(Sorted Sets)
|
类似于集合,但每个成员都关联了一个分数,可以按照分数排序 |
排行榜,如游戏高分玩家列表,可以按分数排序。 实现优先级队列,如任务调度系统。 存储带权重的数据,如商品评分,可以按评分排序。
|
- redis是单线程为什么还这么快?
Redis 被设计为单线程执行模型的主要原因是为了解决线程安全问题,并最大化利用 CPU 在执行简单任务时的性能。
内存操作:Redis 将所有数据存储在内存中,这意味着读写操作的延迟极低。内存访问速度远超磁盘 I/O,这使得 Redis 能够在处理大量数据时保持高速。
避免上下文切换:由于 Redis 是单线程的,所以不存在线程间的上下文切换,这减少了操作系统层面的开销,提高了执行效率。
I/O 多路复用:Redis 使用 I/O 多路复用技术(如 epoll 或 kqueue),这使得它能够在单个线程中同时处理多个客户端的连接和请求。当一个客户端的请求正在等待 I/O 时,Redis 可以处理其他客户端的请求,这极大地提高了 I/O 利用效率。
高效的底层数据结构:Redis 采用了多种高效的数据结构,如跳跃表、字典、压缩列表等,这些数据结构在查询和修改操作上都非常高效。
命令的原子性:Redis 的大多数命令都是原子性的,这意味着它们要么全部执行成功,要么全部失败。这种性质简化了并发控制,使得在单线程环境中更容易保证数据的一致性。
异步操作:从 Redis 4.0 版本开始,Redis 引入了多线程异步处理一些耗时较长的任务,例如异步删除命令 UNLINK。在 Redis 6.0 中,它在核心网络模型中引入了多线程,以进一步提高对于多核 CPU 的利用率,但这不影响其单线程处理客户端请求的核心设计。
命令管道:Redis 支持命令管道,允许客户端一次性发送多个命令,减少网络往返的时间,提高批量处理的效率。
- redis淘汰机制
在服务器内存接近其配置的最大限制时,用来决定哪些键应该被删除以释放内存空间的策略。当Redis运行在内存受限的环境中,例如作为缓存服务器时,这些机制尤其重要,因为它们允许Redis继续接受新的写操作,同时牺牲一部分现有的数据。
策略 |
描述 |
noeviction |
默认的策略。当内存达到配置的最大值时,Redis不会主动删除任何键。相反,它会返回一个错误给尝试写入新数据的客户端,除了DEL, BLPOP, BRPOP, BRPOPLPUSH等少数几个命令仍然会被执行。 |
allkeys-lru |
在所有键中使用最近最少使用(Least Recently Used, LRU)算法来淘汰数据。这意味着最长时间未被访问的键将被删除。 |
allkeys-random |
随机地从所有键中选择键进行删除。 |
volatile-lru |
只在设置了过期时间的键中使用LRU算法来淘汰数据。这通常意味着较旧的键将被优先删除。 |
volatile-random |
随机地从设置了过期时间的键中选择键进行删除。 |
volatile-ttl |
在设置了过期时间的键中,优先淘汰那些过期时间最近的键。 |
volatile-lfu(4.0) |
使用最少频率使用(Least Frequently Used, LFU)算法来淘汰设置了过期时间的键。 |
通过修改redis.conf配置文件中的maxmemory-policy指令来设置这些策略,或者使用CONFIG SET maxmemory-policy <policy>命令来动态更改策略。
Redis还提供了两种过期策略:定期删除和惰性删除,但这些不是真正的淘汰机制,而是用于管理设置了过期时间的键的策略。
定期删除: Redis每隔一段时间(默认为100毫秒)会随机检查一小部分设置了过期时间的键,并删除其中已过期的键。
惰性删除: 当访问一个键时,Redis会检查这个键是否已经过期。如果过期,则立即删除而不返回任何数据。
- Redis 的持久化机制
有两种,第一种是快照,第二种是 AOF 日志。快照是一次全量备份,AOF 日志是连续的增量备份。
Redis 使用操作系统的多进程 COW(Copy On Write) 机制来实现快照持久化。
Copy-on-Write(COW,写时复制)是一种在计算机科学中广泛使用的优化技术。COW的核心思想是,当多个进程共享相同的内存区域或文件内容时,只有在某个进程试图修改这些共享资源时,系统才会创建该资源的一个副本供该进程独享。
这样做的主要好处是可以显著减少内存使用和磁盘占用,因为它避免了不必要的数据复制,直到真正需要修改数据时才进行复制。
在多进程环境中的应用
在fork()系统调用中。当一个父进程通过fork()创建一个新的子进程时,子进程会获得与父进程完全相同的虚拟地址空间,包括所有的内存页面。但是,如果没有COW机制,这将意味着每个进程都需要独立的物理内存页,这会极大地消耗系统的物理内存。
使用COW,父进程和子进程最初共享相同的内存页面。只有当其中一个进程试图修改某个页面时,操作系统才会创建该页面的一个副本,并只将修改写入这个副本中。这个过程对应用程序是透明的,因此从应用程序的角度来看,每个进程都有自己的完整地址空间。
COW 的实现细节
在Linux系统中,COW是通过页表和内存映射实现的。当进程创建时,其页表指向的是共享的物理页面。当进程尝试修改一个页面时,MMU(Memory Management Unit,内存管理单元)会触发一个缺页异常,操作系统内核接收到这个异常后,会为该进程分配一个新的物理页面,更新页表,然后重新执行导致异常的指令。这个过程对用户空间的程序来说是完全透明的。
- redis部分机制问题
Redis 集群
Redis 集群主要解决的是水平扩展问题,即如何在多台机器上分布存储数据,以支持更大的数据量和更高的并发访问。Redis 集群有以下特点:
数据分区:数据被分布在多个 Redis 节点上,每个节点负责一部分数据。这通常通过哈希槽(hash slot)的概念来实现,整个集群有16384个哈希槽,每个键根据其哈希值映射到特定的哈希槽,再进一步映射到具体的节点上。
自动故障转移:如果一个节点失败,集群会尝试自动将数据重定向到其他节点,或者重新分配哈希槽,以保持服务的可用性。
读写分离:每个主节点可以有多个从节点,从节点用于读取操作,以减轻主节点的负担,提高读性能。
线性可扩展性:可以通过添加更多节点来线性提升集群的性能和容量。
Redis 哨兵机制
Redis 哨兵机制主要关注的是高可用性,尤其是针对单个实例的故障恢复。哨兵机制有以下特点:
监控:哨兵进程会持续监控主节点和从节点的状态,检查它们是否正常运行。
通知:当发现节点出现问题时,哨兵可以向管理员发送警报,也可以触发自动故障转移。
自动故障转移:当主节点失败时,哨兵会从从节点中选举出一个新的主节点,然后更新客户端和其他哨兵关于新主节点的信息,使集群恢复正常服务。
配置中心:哨兵还可以作为配置中心,帮助客户端找到正确的主节点信息。
比较
适用场景:
集群适合于需要高并发读写和大规模数据存储的应用场景。
哨兵适合于单个实例或小规模集群的高可用性需求,特别是对于数据安全性和服务连续性要求较高的场景。
数据一致性:
集群模式下,数据分布在多个节点,一致性依赖于集群的配置和实现。
哨兵模式下,数据的一致性主要依赖于主从复制机制。
实现复杂度:
集群模式涉及复杂的分布式算法和数据分布逻辑。
哨兵模式相对简单,主要关注于监控和故障转移。