Skip to content

Commit e1315c6

Browse files
committed
update redis
1 parent e7f2a87 commit e1315c6

2 files changed

Lines changed: 54 additions & 13 deletions

File tree

notes/database/Redis.md

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@
1717
- [位图](#%E4%BD%8D%E5%9B%BE)
1818
- [HyperLogLog](#hyperloglog)
1919
- [布隆过滤器](#%E5%B8%83%E9%9A%86%E8%BF%87%E6%BB%A4%E5%99%A8)
20-
- [Scan](#scan)
21-
- [GeoHash](#geohash)
22-
- [简单限流](#%E7%AE%80%E5%8D%95%E9%99%90%E6%B5%81)
23-
- [漏斗限流](#%E6%BC%8F%E6%96%97%E9%99%90%E6%B5%81)
2420
- [Redis单进程单线程方式](#redis%E5%8D%95%E8%BF%9B%E7%A8%8B%E5%8D%95%E7%BA%BF%E7%A8%8B%E6%96%B9%E5%BC%8F)
2521
- [单进程单线程好处](#%E5%8D%95%E8%BF%9B%E7%A8%8B%E5%8D%95%E7%BA%BF%E7%A8%8B%E5%A5%BD%E5%A4%84)
2622
- [单进程单线程弊端](#%E5%8D%95%E8%BF%9B%E7%A8%8B%E5%8D%95%E7%BA%BF%E7%A8%8B%E5%BC%8A%E7%AB%AF)
@@ -31,6 +27,8 @@
3127
- [Redis两种持久化方式优缺点](#redis%E4%B8%A4%E7%A7%8D%E6%8C%81%E4%B9%85%E5%8C%96%E6%96%B9%E5%BC%8F%E4%BC%98%E7%BC%BA%E7%82%B9)
3228
- [Redis常见的性能问题都有哪些?如何解决?](#redis%E5%B8%B8%E8%A7%81%E7%9A%84%E6%80%A7%E8%83%BD%E9%97%AE%E9%A2%98%E9%83%BD%E6%9C%89%E5%93%AA%E4%BA%9B%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3)
3329
- [Redis提供6种数据淘汰策略](#redis%E6%8F%90%E4%BE%9B6%E7%A7%8D%E6%95%B0%E6%8D%AE%E6%B7%98%E6%B1%B0%E7%AD%96%E7%95%A5)
30+
- [Redis设置过期时间的原理](#redis%E8%AE%BE%E7%BD%AE%E8%BF%87%E6%9C%9F%E6%97%B6%E9%97%B4%E7%9A%84%E5%8E%9F%E7%90%86)
31+
- [定时扫描策略](#%E5%AE%9A%E6%97%B6%E6%89%AB%E6%8F%8F%E7%AD%96%E7%95%A5)
3432

3533
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
3634

@@ -202,14 +200,40 @@ GETSET lock.foo <current Unix time + lock timeout + 1>
202200
如果在C1之前,有个叫C2的客户端比C1快一步执行了上面的操作,那么C1拿到的时间戳是个未超时的值,这时C1没有如期获得锁,需要再次等待或重试。尽管C1没拿到锁,但它改写了C2设置的锁的超时值,不过这一点非常微小的误差带来的影响可以忽略不计。
203201

204202
### 延时队列
203+
延时队列可以通过 Redis 的 zset(有序列表) 来实现。我们将消息序列化成一个字符串作为 zset 的value,这个消息的到期处理时间作为score,然后用多个线程轮询 zset 获取到期的任务进行处理,多个线程是为了保障可用性,万一挂了一个线程还有其它线程可以继续处理。因为有多个线程,所以需要考虑并发争抢任务,确保任务不能被多次执行。
204+
205205
### 位图
206+
Redis 提供了位图统计指令 bitcount 和位图查找指令 bitpos,bitcount 用来统计指定位置范围内 1 的个数,bitpos 用来查找指定范围内出现的第一个 0 或 1。
207+
比如我们可以通过 bitcount 统计用户一共签到了多少天,通过 bitpos 指令查找用户从哪一天开始第一次签到。如果指定了范围参数[start, end],就可以统计在某个时间范围内用户签到了多少天,用户自某天以后的哪天开始签到。
206208
### HyperLogLog
207209
HyperLogLog 数据结构是 Redis 的高级数据结构,HyperLogLog 提供不精确的去重计数方案,虽然不精确但是也不是非常不精确,标准误差是 0.81%,这样的精确度已经可以满足上面的 UV 统计需求了
208210
### 布隆过滤器
209-
### Scan
210-
### GeoHash
211-
### 简单限流
212-
### 漏斗限流
211+
布隆过滤器是一个神奇的数据结构,可以用来判断一个元素是否在一个集合中。很常用的一个功能是用来去重。
212+
213+
redis 在 4.0 的版本中加入了 module 功能,布隆过滤器可以通过 module 的形式添加到 redis 中,所以使用 redis 4.0 以上的版本可以通过加载 module 来使用 redis 中的布隆过滤器。但是这不是最简单的方式,使用 docker 可以直接在 redis 中体验布隆过滤器。
214+
215+
每个布隆过滤器对应到 Redis 的数据结构里面就是一个大型的位数组和几个不一样的无偏 hash 函数。所谓无偏就是能够把元素的 hash 值算得比较均匀。
216+
217+
向布隆过滤器中添加 key 时,会使用多个 hash 函数对 key 进行 hash 算得一个整数索引值然后对位数组长度进行取模运算得到一个位置,每个 hash 函数都会算得一个不同的位置。再把位数组的这几个位置都置为 1 就完成了 add 操作。
218+
219+
向布隆过滤器询问 key 是否存在时,跟 add 一样,也会把 hash 的几个位置都算出来,看看位数组中这几个位置是否都位 1,只要有一个位为 0,那么说明布隆过滤器中这个 key 不存在。如果都是 1,这并不能说明这个 key 就一定存在,只是极有可能存在,因为这些位被置为 1 可能是因为其它的 key 存在所致。
220+
221+
redis 布隆过滤器主要就两个命令:
222+
- bf.add 添加元素到布隆过滤器中:bf.add urls https://baidu.com
223+
- bf.exists 判断某个元素是否在过滤器中:bf.exists urls https://baidu.com
224+
225+
布隆过滤器存在误判的情况,在 redis 中有两个值决定布隆过滤器的准确率:
226+
- error_rate:允许布隆过滤器的错误率,这个值越低,需要的存储空间就越大,对于不需要过于精确的场合,error_rate设置稍大一点也无伤大雅。
227+
- initial_size:布隆过滤器可以储存的元素个数,估计的过大,会浪费存储空间,估计的过小,就会影响准确率。
228+
229+
redis 中有一个命令可以来设置这两个值:
230+
>bf.reserve urls 0.01 100
231+
232+
代码三个参数的含义:
233+
- 第一个值是布隆过滤器的名字。
234+
- 第二个值为 error_rate 的值。
235+
- 第三个值为 initial_size 的值。
236+
213237

214238

215239

@@ -282,21 +306,37 @@ HyperLogLog 数据结构是 Redis 的高级数据结构,HyperLogLog 提供不
282306
4. RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快
283307

284308

285-
286309
## Redis常见的性能问题都有哪些?如何解决?
287310
1. Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。
288311
2. Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
289312
3. Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。
290313
4. Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内
291314

292315

293-
294-
295-
296316
## Redis提供6种数据淘汰策略
297317
1. volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
298318
2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
299319
3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
300320
4. allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
301321
5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
302-
6. no-enviction(驱逐):禁止驱逐数据
322+
6. no-enviction(驱逐):禁止驱逐数据
323+
324+
## Redis设置过期时间的原理
325+
Redis 提供的诸多命令中,EXPIRE、EXPIREAT、PEXPIRE、PEXPIREAT 以及 SETEX 和 PSETEX 均可以用来设置一条 Key-Value 对的过期时间。
326+
327+
Redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,过期键的处理就是把过期键删除,这里的操作主要是针对过期字段处理的。
328+
329+
Redis中有三种处理策略:定时删除、惰性删除和定期删除
330+
1. 定时删除:在设置键的过期时间的时候创建一个定时器,当过期时间到的时候立马执行删除操作。不过这种处理方式是即时的,不管这个时间内有多少过期键,不管服务器现在的运行状况,都会立马执行,所以对CPU不是很友好。但是这在最大程度上释放了内存,所以这种方式算是一种内存优先优化策略。
331+
2. 惰性删除:惰性删除策略不会在键过期的时候立马删除,而是当外部指令获取这个键的时候才会主动删除。处理过程为:接收get执行、判断是否过期、执行删除操作、返回nil(空)。
332+
3. 定期删除:定期删除是设置一个时间间隔,每个时间段都会检测是否有过期键,如果有执行删除操作。
333+
334+
335+
### 定时扫描策略
336+
Redis 默认会每秒进行十次过期扫描,过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略。
337+
1. 从过期字典中随机 20 个 key;
338+
2. 删除这 20 个 key 中已经过期的 key;
339+
3. 如果过期的 key 比率超过 1/4,那就重复步骤 1;
340+
341+
同时,为了保证过期扫描不会出现循环过度,导致线程卡死现象,算法还增加了扫描时间的上限,默认不会超过 25ms。
342+

notes/java/Java容器.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
33
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
44

5+
- [Java集合类框架图](#java%E9%9B%86%E5%90%88%E7%B1%BB%E6%A1%86%E6%9E%B6%E5%9B%BE)
56
- [HashSet和TreeSet区别](#hashset%E5%92%8Ctreeset%E5%8C%BA%E5%88%AB)
67
- [讲一下LinkedHashMap](#%E8%AE%B2%E4%B8%80%E4%B8%8Blinkedhashmap)
78
- [Java8 中HashMap的优化(引入红黑树的数据结构和扩容的优化)](#java8-%E4%B8%ADhashmap%E7%9A%84%E4%BC%98%E5%8C%96%E5%BC%95%E5%85%A5%E7%BA%A2%E9%BB%91%E6%A0%91%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E6%89%A9%E5%AE%B9%E7%9A%84%E4%BC%98%E5%8C%96)

0 commit comments

Comments
 (0)