Redis从出门到高可用--瑞士军刀Redis

Redis从出门到高可用–瑞士军刀Redis

一、慢查询

慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阀值,就将这条命令的相关信息(慢查询ID,发生时间戳,耗时,命令的详细信息)记录下来。

慢查询其实是一个先进先出的队列,有固定的长度,保存在内存内。

1.1、生命周期
image

两点说明:
1、慢查询发生在第三阶段
2、客户端超时不一定慢查询,但是慢查询是客户端超时的一个可能因素。

1.2、两个配置

1、慢查询的预设阀值  slowlog-log-slower-than

slowlog-log-slower-than参数就是预设阀值,单位是微秒,默认值是1000,如果一条命令的执行时间超过10000微妙,那么它将被记录在慢查询日志中。

如果slowlog-log-slower-than的值是0,则会记录所有命令。

如果slowlog-log-slower-than的值小于0,则任何命令都不会记录日志。


2、慢查询日志的长度slowlog-max-len
slowlog-max-len只是说明了慢查询日志最多存储多少条。Redis使用一个列表来存储慢查询日志,showlog-max-len就是列表的最大
长度。当慢查询日志已经到达列表的最大长度时,又有慢查询日志要进入列表,则最早插入列表的日志将会被移出列表,新日志被插入列表的末尾。

1.3、三个命令

1、获取慢查询日志slowlog get [n]

命令:slowlog get [N]

选型:N,可选,代表获取的日志条数

例如:showlog get 5


2、获取慢查询日志列表的当前长度slowlog len

命令:slowlog len

返回:慢日志列表的当前长度

例如:slowlog len

返回:2


3、慢查询日志重置slowlog reset

慢查询日志重置实际是对列表做清理操作。

命令:slowlog reset

例如:slowlog reset

slowlog len

返回: 0

1.4、运维经验

1、slowlog-max-len:不要设置过小,通常设置1000左右
2、slowlog-log-lower-than:不要设置过大,默认10ms,通常设置1ms
3、定期持久化慢查询:慢查询日志是一个先进先出队列,慢查询较多的情况下,可能会丢失部分慢查询命令,可以定期执行slow
get命令将慢查询日志持久化到其他存储中。然后制作可视化界面查询

二、pipeline

image
image

2.1、什么是流水线

image

image

两点注意:
1、Redis的命令执行时间是微妙级的
2、pipeline每次条数要控制

2.2、客户端实现

实现:

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
1
2
3
4
5
没有pipeline:
Jedis jedis = new Jedis("127.0.0.1",6379);
for(int i=0;i<=10000;i++){
jedis.hset("hashkey"+i,"field"+i,"value"+i);
}
1
2
3
4
5
6
7
8
使用pipeline:
Jedis jedis = new Jedis("127.0.0.1",6379);
for(int i=0;i<=100;i++){
Pipeline pipeline = jedis.pipelined();
for(int j=0;j<(i+1)*100;j++){
pipeline.hset("hashkey"+j,"field"+j,"value"+j)
}
}

2.3、与原生操作相比

image

image

即:pipeline会被分成一个个的子pipeline执行

2.4、使用建议

1、注意每次pipeline携带数据量
2、pipeline每次只能作用在一个Redis节点上

三、发布订阅

3.1、角色
发布者(publisher)
订阅者(subscriber)
频道(channel)
3.2、模型

image

3.3、API
publish
publish channel message
subscribe

unsubscribe

publish:

1
2
3
4
5
6
7
127.0.0.1:6382> PUBLISH sohu:tv "hello world"
(integer) 1
127.0.0.1:6382> PUBLISH sohu:tv "hello world2"
(integer) 1
127.0.0.1:6382> PUBLISH sohu:tv "hello world3"
(integer) 1
127.0.0.1:6382>

subscriber

1
2
3
4
5
6
7
8
9
10
11
12
13
14
127.0.0.1:6382> SUBSCRIBE sohu:tv
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "sohu:tv"
3) (integer) 1
1) "message"
2) "sohu:tv"
3) "hello world"
1) "message"
2) "sohu:tv"
3) "hello world2"
1) "message"
2) "sohu:tv"
3) "hello world3"
3.4、发布订阅与消息队列

image

四、Bitmap

4.1、位图

image

4.2、相关API

setbit

setbit key offset value:给位图指定索引设置值
1
2
3
4
5
6
7
8
9
127.0.0.1:6382> set hello big
OK
127.0.0.1:6382> getbit hello 1
(integer) 1
127.0.0.1:6382> setbit hello 7 1
(integer) 0
127.0.0.1:6382> get hello
"cig"
127.0.0.1:6382>

getbit

1
2
3
4
5
6
7
8
9
10
11
127.0.0.1:6382> setbit unique:user 0 1
(integer) 0
127.0.0.1:6382> setbit unique:user 5 1
(integer) 0
127.0.0.1:6382> setbit unique:user 11 1
(integer) 0
127.0.0.1:6382> setbit unique:user 15 1
(integer) 0
127.0.0.1:6382> setbit unique:user 19 1
(integer) 0
127.0.0.1:6382>

bitcount

bitcount key [start end]
获取位图指定范围(start到end,单位字节,默认所有)位置为1的个数
1
2
3
127.0.0.1:6382> bitcount unique:user 1 3
(integer) 3
127.0.0.1:6382>

bitop

bitop op destkey key [key....]
做多个Bitmap的and(交)、or(并)、not(非)、xor(异或)操作
4.3、独立用户统计

案例:

1、使用set和Bitmap
2、某网站1亿用户,5千万的独立用户统计

使用两种数据结构统计:

image

image

但是Bitmap并不是绝对的好:

如:只有10万的独立用户呢?

image

4.4、使用经验:
1、Bitmap是type=string,最大521M
2、注意setbit时的偏移量,可能有较大的耗时
3、位图不是绝对的好

五、HyperLogLog

5.1、新的数据结构?
1、基于HyperLogLog算法:使用极小的空间完成独立用户统计
2、本质还是字符串
5.2、三个API
1、pfadd key element [element ...]:向pyherloglog添加元素
2、pfcount key [key...]:计算hyperloglog的独立总数
3、pfmerge destkey sourcekey [sourcekey....]:合并多个hyperloglog
1
2
3
4
5
6
7
8
9
10
11
127.0.0.1:6382> bitcount unique:user 1 3
(integer) 3
127.0.0.1:6382> pfadd 20180507:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-4"
(integer) 1
127.0.0.1:6382> pfcount 20180507:unique:ids
(integer) 4
127.0.0.1:6382> pfadd 20180507:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-99"
(integer) 1
127.0.0.1:6382> pfcount 20180507:unique:ids
(integer) 5
127.0.0.1:6382>
1
2
3
4
5
6
7
8
9
127.0.0.1:6382> pfadd 20180508:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-4"
(integer) 1
127.0.0.1:6382> pfcount 20180508:unique:ids
(integer) 4
127.0.0.1:6382> pfmerge 2018050708:unique:ids 20180507:unique:ids 20180508:unique:ids
OK
127.0.0.1:6382> pfcount 2018050708:unique:ids
(integer) 5
127.0.0.1:6382>
5.3、内存的消耗

1百万独立用户统计

image

5.4、使用经验
1、取决于你能否容忍错误:因为hyperloglog会出错,错误率为0.81%

2、是否需要单挑数据,hyperloglog结构数据是不能取出单条数据的

六、GEO

redis3.2以上版本支持

6.1、GEO是什么
6.2、5个城市经纬度

image

6.3、API

geoadd

geo key longitude latitude member [longitude latitude menber]:增加地理位置信息

image

geopos

geopos key menber [member...]:获取地理位置信息

image

geodist

geodist key member1 member2 [unit]:获取两个地理位置的距离,unit(距离单位):m,km,mi,ft

image
georadius

6.4、相关说明
1、redis 3.2+
2、type geoKey = zset

文章目录
  1. 1. 一、慢查询
  2. 2. 二、pipeline
  3. 3. 三、发布订阅
    1. 3.0.0.0.1. 3.1、角色
    2. 3.0.0.0.2. 3.2、模型
    3. 3.0.0.0.3. 3.3、API
    4. 3.0.0.0.4. 3.4、发布订阅与消息队列
  • 3.1.
  • 4. 四、Bitmap
    1. 4.0.0.0.1. 4.1、位图
    2. 4.0.0.0.2. 4.2、相关API
    3. 4.0.0.0.3. 4.3、独立用户统计
    4. 4.0.0.0.4. 4.4、使用经验:
  • 5. 五、HyperLogLog
    1. 5.0.0.0.1. 5.1、新的数据结构?
    2. 5.0.0.0.2. 5.2、三个API
    3. 5.0.0.0.3. 5.3、内存的消耗
    4. 5.0.0.0.4. 5.4、使用经验
  • 6. 六、GEO
    1. 6.0.0.0.1. 6.1、GEO是什么
    2. 6.0.0.0.2. 6.2、5个城市经纬度
    3. 6.0.0.0.3. 6.3、API
    4. 6.0.0.0.4. 6.4、相关说明