
Redis
文章平均质量分 92
非关系型数据库Redis。
程序员小潘
Java开发工程师,现居杭州,优快云博客专家,热衷于分享计算机编程相关知识,欢迎关注~
展开
-
Redis分布式可重入锁实现方案
在单进程环境下,要保证一个代码块的同步执行,直接用关键字或即可。在分布式环境下,要保证多个节点的线程对代码块的同步访问,就必须要用到分布式锁方案。分布式锁实现方案有很多,有基于关系型数据库行锁实现的;有基于ZooKeeper临时顺序节点实现的;还有基于 Redis setnx 命令实现的。本文介绍一下基于 Redis 实现的分布式锁方案。原创 2024-02-18 15:03:32 · 2433 阅读 · 0 评论 -
Redis主从复制流程
主从复制是 Redis 实现服务高可用的关键特性之一,主节点通过把写命令异步传播给从节点的方式来实现数据同步。同时,为了避免从库因为网络问题断开导致数据不一致,主库会开辟一块主从复制积压缓冲区 repl_backlog 缓存最近的写命令,待从库恢复连接后,可以直接走增量同步。为了避免缓冲区膨胀,repl_backlog 采用固定大小循环写的方式,一旦从库落后的太久,需要增量同步的日志被主库覆盖掉了,就不得不触发全量同步,因此建议线上可以适当调大缓冲区的大小。原创 2023-10-17 17:42:25 · 265 阅读 · 1 评论 -
Redis AOF持久化和ReWrite
Redis 的 RDB 持久化机制简单直接,把某一时刻的所有键值对以二进制的方式写入到磁盘,特点是恢复速度快,尤其适合数据备份、主从复制场景。但如果你的目的是要保证数据可靠性,RDB 就不太适合了,因为 RDB 持久化不宜频繁触发,如果 Redis 触发 RDB 后又有新的数据写入,且还没来得及触发下一次 RDB 就宕机了,中间的数据就会丢失。在这种场景下,我们就急需一种增量备份的方式,只记录上一次 RDB 到现在为止所有的变更记录就好了,相较于全量备份,增量备份的数据量就小得多了。原创 2023-10-17 17:41:47 · 802 阅读 · 0 评论 -
Redis RDB持久化
我们知道 Redis 之所以快,很大程度是因为它的数据直接放在内存里,而内存是易失性存储器,只有通电才存储数据,断电数据就会丢失。这个时候就要看你的应用场景了,如果你只是拿 Redis 做关系型数据库的缓存,来加速数据的访问效率,那么 Redis 数据即使丢了也不影响,可以重新从关系型数据库中重新加载一遍。但如果你直接拿 Redis 当做数据库来用,在上面存储业务数据,那么你就要重点关注下 Redis 的持久化机制了。原创 2023-10-17 17:41:11 · 349 阅读 · 0 评论 -
Redis LFU缓存淘汰算法
Redis 在 4.0 版本之前的缓存淘汰算法,只支持 random 和 lru。random 太简单粗暴了,可能把热点数据给淘汰掉,一般不会使用。lru 比 random 好一点,会优先淘汰最久没被访问的数据,但是它也有一个缺点,就是无法真正表示数据的冷热程度。如下示例,A 之前被频繁访问,B 在执行 LRU 淘汰前恰巧被访问了一次,记录了最新的时间戳。此时触发 LRU 淘汰算法,反而会把 A 给淘汰掉。但事实是,A 的热度明显比 B 高。原创 2023-10-17 17:40:21 · 547 阅读 · 0 评论 -
Redis LRU缓存淘汰算法
内存不是无限大的,当我们向 Redis 写入的数据量超过了最大内存限制,Redis 就会启用缓存淘汰策略。配置缓存淘汰策略是有必要的,在使用缓存数据库时,我们要重点关注的一个指标就是缓存命中率,如果数据只会被访问一次,那它的缓存是没有意义的。所以我们要尽可能的提高缓存数据库的性价比,也就是提高缓存命中率。提高缓存命中率最直接的方式,就是尽可能的保证缓存里的总是热数据,冷数据随着时间推移慢慢淘汰掉。所以我们需要一个缓存淘汰算法,那就是 LRU。原创 2023-10-17 17:39:27 · 546 阅读 · 0 评论 -
HyperLogLog算法
现在很多站点基本都有统计 PV 和 UV 的需求,PV 的统计很简单,在 Redis 里面维护一个计数器,页面每访问一次计数器就 +1,获取 PV 就是读取计数器的值。相比之下,UV 的统计就比较麻烦了,因为要对用户去重,UV 统计其实就是基数统计,最简单的做法就是记录下集合中所有不重复的元素。比如,你可以用 Set 来统计,Set 不会存储重复的元素,用户每次访问都把 UserID 写入 Set 集合,最终调用 SCARD 命令获取集合元素数量即可。原创 2023-10-17 17:38:52 · 744 阅读 · 1 评论 -
Redis数据结构之listpack
当数据量较小时,Redis 会优先考虑用 ziplist 来存储 hash、list、zset,这么做可以有效的节省内存空间,因为 ziplist 是一块连续的内存空间,它采用一种紧凑的方式来存储元素。但是它也有缺点,比如查找的时间复杂度高、内存分配的开销、连锁更新的风险等。原创 2023-10-17 17:36:13 · 1201 阅读 · 0 评论 -
Redis数据结构之quicklist
为了节省内存,Redis 推出了 ziplist 数据类型,采用一种更加紧凑的方式来存储 hash、zset 元素。因为查找的时间复杂度是 O(N),且写入需要重新分配内存,所以它仅适用于小数据量的存储,而且它还存在 连锁更新 的风险。为了降低 ziplist 内存分配和连锁更新带来的影响,Redis 又推出了 quicklist 数据结构,我们来一睹它的风采。注意:quicklist只是降低了 ziplist 内存分配和连锁更新带来的影响,没有从根本上解决这些问题。原创 2023-10-17 17:35:37 · 528 阅读 · 0 评论 -
Redis数据结构之ziplist
Redis 为了提高内存效率,设计了一种特殊的数据结构 ziplist(压缩列表)。ziplist 本质是一段字节数组,采用了一种紧凑的、连续存储的格式,可以有效地压缩数据,提高内存效率。hash、zset 在数据量比较小时,会优先用 ziplist 存储数据,否则会分配大量指针,指针本身会占用空间,而且会增加内存的碎片化率。以 hash 为例,可以通过下列配置当 Entry 数量小于 512,且 数据长度小于 64 时使用压缩列表存储,否则采用 哈希表 存储。原创 2023-10-17 17:34:59 · 377 阅读 · 0 评论 -
Redis数据结构之HashTable
哈希表是一种非常常用的数据结构,它具备 O(1) 时间复杂度的查找效率,常被用来索引数据。哈希表在 Redis 中也承担着重要角色,例如:数据类型 Hash 底层就是用的哈希表实现的,数据库所有的键值对也是用一个全局哈希表来存储的。Redis 是如何实现哈希表的呢?原创 2023-10-17 17:34:04 · 965 阅读 · 0 评论 -
Redis EmbeddedString
Redis 写入键值对时,首先会先创建一个 RedisObject 对象来存储 Value。如果写入的 Value 是字符串,那么 Redis 会再根据写入的字符串长度,来创建对应的 sdshdr 来存储字符串,最后把 RedisObject 的 ptr 指针指向 sdshdr。我们来分析下这个过程,首先创建 RedisObject 需要分配一次内存,创建 sdshdr 又需要再分配一次内存。原创 2023-10-17 17:32:40 · 304 阅读 · 0 评论 -
Redis数据结构之SDS
字符串在 Redis 中的应用场景十分广泛,所有的键都是字符串类型,值也可能是字符串类型。Redis 是用 C 语言开发的,在 C 语言中,字符串可以用字符数组来表示,但是 Redis 并没有直接使用原生的字符数组,而是自定义了一个叫 Simple Dynamic String(简单动态字符串,缩写 SDS)的数据结构,它相较于原生字符数组有哪些优势呢?原创 2023-10-17 17:32:01 · 114 阅读 · 0 评论 -
RedisObject
Redis 是一个基于内存的,以 Key-Value 形式存储数据的 NoSQL 数据库。相较于其它 NoSQL 数据库,Redis 提供了更丰富的数据类型和 API,开发者可以基于 Redis 实现数据缓存、消息队列、分布式锁等场景。Redis 底层用一个全局哈希表来存储所有的键值对,Value 是一个指针,指向 Key 对应的数据对象。原创 2023-10-17 17:30:55 · 296 阅读 · 0 评论