redis 高级类型

0、本文包含内容

  1. Redis高级数据类型GEO&HyperLogLog详解
  2. Redis事务机制&乐观锁
  3. Redis内部事件订阅机制keyspace&keyevent
  4. Redis主从架构

1、Redis高级数据类型GEO&HyperLogLog详解

1.1. zset扩展类型geo

1.1.1. GEO功能介绍

GEO功能是在Redis 3.2版本后提供的,支持存储地理坐标的一个数据结构,可以用来做类似摇一摇,附近的人,周边搜索的功能

# 语法类型
geoadd key 经度 纬度 成员 [经度 纬度 成员...]
# geoadd命令必须以标准的x y member结构来接受参数,必须先输入经度后输入纬度

geoadd能够记录的坐标是有限:

  • 非常接近两极的区域无法索引
  • 精确的坐标限制是由 EPSG:900913等坐标系统定义
  • 经度:-180到180度之间
  • 纬度:-85.05112878到85.05112878度之间
  • 如果超出这个范围则会报错

1.1.2. 新增和查询

# 添加一批城市
geoadd china:city 116.408 39.904 beijing 121.445 31.213 shanghai 113.265 23.108 guangzhou 114.109 22.544 shenzhen 108.969 34.285 xian 108.55 34.09 changan 
# 查询
geopos china:city beijing shanghai

1.1.3.获得节点间距离

geodist china:city shanghai beijing km

unit:

  • m : 米
  • km :千米
  • mi :英里
  • ft : 英尺
  • 默认是m
  • 会有0.5%的误差

1.1.4. 周边搜索

georadius china:city 121.445 31.213 1300 km withdist withcoord
georadius china:city 121.445 31.213 1300 km withdist withcoord asc count 3
georadiusbymember china:city beijing 1300 km withdist withcoord asc count 3
  • withdist : 返回节点距离
  • withcoord : 带上坐标
#节点hash
geohash china:city xian changan
1) "wqj7p9ku9e0"
2) "wqj1yjgswk0"

1.1.5. 删除节点

zrem china:city changan

1.1.6. 业务实现

x y name1 x y nam2
x y canyin:123 x y canyin:456

1.2. hyperloglog

这个数据类型其实就做了一件事,统计不重复的数据量
比如要记录我们网站的UV量

sadd 20200208 1 2 3 4 5 6 5 4 3 2 1
scard 20200208

只用来存放基数

pfadd 20200207 1 2 3 4 5 6 5 4 3 2 1 #添加记录基数
pfadd 20200206 1 2 3 4 5 6 7 8 9 10
pfcount 20200206 #返回基数
pfmerge 202002 20200206 20200207 #pfmerge newkey sourcekey1 sourcekey2 合并生成了一个新key,原来的key不会消失

还有一个问题

  • hyperloglog是一个基数估算算法,有一定误差的
  • 误差值在0.81%
  • hyperloglog的key占用空间很小只有12K,而你用set就需要把这些value都要保存,set存一年数据有多大

2. Redis事务&乐观锁

2.1. Redis事务

场景描述:

就是我们的数据操作是一个原子性的

# 看一下redis的场景
# client A                  client B
set name icoding(1)     set name icodingedu(2)
get name(3)             get name
# 这个时候数据就串了

事务需要边界

multi # 开启事务
set name icoding
get name
exec # 执行事务

discard # 回滚事务

事务执行过程中错误回退机制

  • 如果命令错误则自动回滚
  • 如果命令正确但语法错误,正确的语句都会被执行

2.2. Redis的乐观锁

业务场景距离

库存:store 1000-->100 / + 1000(三个业务人员incrby)

数据的状态:如果在你修改前已经被修改了,就不能再修改成功了?

# watch key1 key2 命令
# 只要在事务外watch了一个key或多个key,在事务还没有执行完毕的时候,watch其中的key被修改后,整个事务回滚
set store 10
watch store
multi
incrby store 100
get store
exec
  • watch在事务执行完毕后就释放了
  • watch的key如果在事务执行过程中失效了,事务也不受watch影响
  • watch只能在事务外执行
  • 客户端如果断开,watch也就失效了

事务执行过程中错误回退机制

  • 如果命令错误则自动回退
  • 如果命令正确但语法错误,正确的语句会被执行

3. Redis内部事件订阅机制keyspace&keyevent

# 进入redis的客户端
subscribe java php #订阅了两个通道
pubstribe java springboot #发布通道
psubscribe j* p* #通配频道

3.1. 应用的业务场景

订单超时2小时未支付,需要关闭,如何实现?

  1. Quartz来做任务调度,定时执行巡检任务,5分钟巡检一次,会有4分59秒的巡检超时
  2. Timer,java的定时器,秒为单位,数据量大的时候性能就成瓶颈了
  3. Quartz+Timer ,Quartz拿出5分钟内将要充实的订单,然后在启用多线程以Timer每秒的方式去检查,但业务功能就比较复杂了
  4. 有没有一种功能,有个hook能通知我们我失效了?通知我执行业务
  5. 假设:expire 7200 秒过期后通知我,这就是实现了第4种方案了?

Redis在2.8版本后,推出keyspace notifcations特性,类似数据库的trigger触发器

keyspace notifications是基于sub/pub发布订阅机制的,可以接收对数据库中影响key操作的所有事件:比如del、set、expire(过期时间)

3.2. 接收的事件类型

有两种:keyspace、keyevent

keyspace : 是key触发的事件的具体操作

keyevent : 是事件影响的键名

# pub这个动作是系统自动发布的
127.0.0.1:6379> del mykey
# 数据库0会发布以下两个信息
publish __keyspace@0__:mykey del
publish __keyevent@0__:del mykey

3.3. 开启系统通知

redis.conf配置文件里

# 这都是配置项
#  K     Keyspace events, published with __keyspace@<db>__ prefix.
#  E     Keyevent events, published with __keyevent@<db>__ prefix.
#  g     Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
#  $     String commands
#  l     List commands
#  s     Set commands
#  h     Hash commands
#  z     Sorted set commands
#  x     Expired events (events generated every time a key expires)
#  e     Evicted events (events generated when a key is evicted for maxmemory)
#  A     Alias for g$lshzxe, so that the "AKE" string means all the events.
# 开关 在redis.conf配置里
notify-keyspace-events "" #默认空字符串,是关闭状态
notify-keyspace-events "KEx" #配置文件里只配置了space和event的expried事件,就只自动发布这个事件

统配订阅

notify-keyspace-events "KEA"
set username gavin ex 10 #set事件,expire事件
psubscribe __key*@*__:*
#返回事件通知
4) "set"
1) "pmessage"
2) "__key*@*__:*"
3) "__keyevent@0__:set"
4) "username"
1) "pmessage"
2) "__key*@*__:*"
3) "__keyspace@0__:username"
4) "expire"
1) "pmessage"
2) "__key*@*__:*"
3) "__keyevent@0__:expire"
4) "username"

1) "pmessage"
2) "__key*@*__:*"
3) "__keyspace@0__:username"
4) "expired"
1) "pmessage"
2) "__key*@*__:*"
3) "__keyevent@0__:expired"
4) "username"

subscribe __keyevent@0__:expired

3.4. Springboot订阅通知

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

4. Redis主从架构

4.1. 主从原理分析

主从出现的原因

主从出现的原因

  • 高并发
    • 官方数据表示Redis的读数据11w/s左右,写速度是8w/s左右
    • Redis尽量少写多读,符合缓存的适用要求
    • 可以通过主从架构来进行读写分离
  • HA
    • 如果有一个以上的从库就会对节点进行备份

同步的过程中一定要开启持久化

  • 如果master出现宕机内存丢失,从库也会删除
  • master进行功能性重启,内存数据丢失,也会同步给slave

主从复制原理

  • 当slave第一次连接时,会触发全量同步,如果已经连接过了,只会同步新增数据
  • 全量备份分为落盘和不落盘两种形式,默认是落盘
# 不落盘复制配置 yes不落盘,no落盘
repl-diskless-sync no
# 等待其他slave连接的一个时间周期,单位是秒
repl-diskless-sync-delay 5
  • 支持断点续传
  • 如果从库过多会导致占用带宽较大,所以从不易过多

主从的结构除了一对多,还可以是树形的,树形结构用的比较少

树形结构

4.2. 主从设置

#可以通过命令看一下主从信息,v5.x版本前从是用slave表示,之后换成replication
info replication
#修改slave的redis.conf
replicaof 192.168.1.100 6379 #master的ip,master的端口
masterauth icoding #主机的访问密码
# yes 主从复制中,从服务器可以响应客户端请求
# no 主从复制中,从服务器将阻塞所有请求,有客户端请求时返回“SYNC with master in progress”;
replica-serve-stale-data yes
# slave节点只允许read 默认就是 yes
# 这个配置只对slave节点才生效,对master节点没作用
replica-read-only yes 
# slave根据指定的时间间隔向master发送ping请求
# 时间间隔可以通过 repl-ping-replica-period 来设置,默认10秒
repl-ping-replica-period 10
# 复制连接超时时间。
# master和slave都有超时时间的设置。
# master检测到slave上次发送的时间超过repl-timeout,即认为slave离线,清除该slave信息。
# slave检测到上次和master交互的时间超过repl-timeout,则认为master离线。
# 需要注意的是repl-timeout需要设置一个比repl-ping-slave-period更大的值,不然会经常检测到超时。
repl-timeout 60
# 是否禁止复制tcp链接的tcp nodelay参数,可传递yes或者no。
# 默认是no,即使用tcp nodelay,允许小包的发送。对于延时敏感型,同时数据传输量比较小的应用,开启TCP_NODELAY选项无疑是一个正确的选择
# 如果master设置了yes来禁止tcp nodelay设置,在把数据复制给slave的时候,会减少包的数量和更小的网络带宽。
# 但是这也可能带来数据的延迟。
# 默认我们推荐更小的延迟,但是在数据量传输很大的场景下,建议选择yes。
repl-disable-tcp-nodelay no
# 复制缓冲区大小,这是一个环形复制缓冲区,用来保存最新复制的命令。
# 这样在slave离线的时候,不需要完全复制master的数据,如果可以执行部分同步,只需要把缓冲区的部分数据复制给slave,就能恢复正常复制状态。
# 缓冲区的大小越大,slave离线的时间可以更长,复制缓冲区只有在有slave连接的时候才分配内存。
# 没有slave的一段时间,内存会被释放出来,默认1m。
repl-backlog-size 5mb
# master没有slave一段时间会释放复制缓冲区的内存,repl-backlog-ttl用来设置该时间长度。
# 单位为秒。
repl-backlog-ttl 3600
# 当master不可用,Sentinel会根据slave的优先级选举一个master。
# 最低的优先级的slave,当选master。
# 而配置成0,永远不会被选举。
# 注意:要实现Sentinel自动选举,至少需要2台slave。
replica-priority 100
# redis提供了可以让master停止写入的方式,如果配置了min-slaves-to-write,健康的slave的个数小于N,mater就禁止写入。
# master最少得有多少个健康的slave存活才能执行写命令。
# 这个配置虽然不能保证N个slave都一定能接收到master的写操作,但是能避免没有足够健康的slave的时候,master不能写入来避免数据丢失。
# 设置为0是关闭该功能,默认也是0。
min-replicas-to-write 2
# 延迟小于min-replicas-max-lag秒的slave才认为是健康的slave。
min-replicas-max-lag 10
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容

  • 1. Redis键(Key) Redis keys命令 2. Redis HyperLogLog Redis Hy...
    鹊南飞_阅读 63,190评论 0 5
  • 文章导读: 了解数据库的背景,它都是在服务器端,所以我们不能接触,涉及到一个远程连接操作 服务器和客户端的分别,服...
    创造new_world阅读 148评论 0 0
  • 一、与Python交互 引入模块from redis import * 这个模块中提供了StrictRedis对象...
    Ricsy阅读 252评论 0 1
  • Redis主从复制的过程: 1、Slave与master建立连接,发送sync同步命令。 2、 Master会启动...
    jaymz明阅读 172评论 0 0
  • 七律/红刺玫 作者:心博、图片:网络 追源应是野蔷薇,变种脱胎生陌圻。 广被绒毛妆本色,遍生皮刺显雄威。 娇颜拖住...
    心博1阅读 528评论 1 2