Redis详解(非关系型数据库)

博主专注于做Java程序开发相关技术分享,旨在与各路大神做技术交流,觉得不错的朋友,点个关注,有想深度交流,也可参考博主其他文章:java架构师知识技能图谱-优快云博客

前言

上文介绍了关系型数据库,但是在日常开发中,业务数据除了会保存在关系型数据库中外,我们也会遇到一些数据并不适合用关系型数据保存,而更适合保存于非关系型数据库中。所以,本文主要介绍非关系型数据库的一些功能

1.缓存数据库

1.1 作用

a.将热点数据存储在内存中,提高程序的响应速度

b.减少数据库的IO压力

c.容易做熔断机制,当数据库挂掉后,可以将请求打在缓存上,继续对外提高服务

1.2 memcache

a.优点

支持简单的数据类型,即hash(key-value)

b.缺点

不支持数据的持久化,服务器宕机,数据无法保存

不支持主从

不支持分片(分片:将大数据分布到多个物理节点的分区方案)

1.3redis

由于memcache本身的一些原因,所以实际开发中的很多场景,并不适用,而用redis做缓存数据库才是大部分公司的选择

1.3.1 优点

相较于memcache,redis 具有以下优点

a.支持的数据类型丰富,支持持久化,支持主从,支持分片

b.查询效率快 100000+QPS (QPS:query per second 每秒查询次数)

1.3.2 特点

a.完全基于内存,绝大部分请求是内存操作,执行效率高,读写数据时,不会受到硬盘IO的速率限制,C语言编写

b.数据结构简单,对数据操作简单

  redis的数据存储结构是hash(key-value),存储和查询的时间复杂度为O(1),但其中的value 又支持多种数据结构

c.采用单线程,单线程也能处理高并发请求,想多核也可启动多实例

  注意:并发并不是并行,并行性意味着服务器可以同时执行几个事情,具有多个计算单元,而并发IO流是一个计算单元可以处理多个客户端的IO流

  读与写都由主线程串行化来执行,避免了频繁上下文切换与锁竞争

  实践发现CPU并非是redis的性能瓶颈

d.采用多路I/O复用模型,非阻塞的IO

  1)读写操作,在单线程等待用户输入都是阻塞的,但多路I/O复用可解决这个问题

  2)FD:File Descripter 文件描述符(操作系统中,一个打开的文件通过唯一的描述符进行引用,该描述符是打开文件的元数据到文件本身的映射,每个进程都会有自己的一个文件描述符列表)

  3)I/O多路复用函数:epoll/kqueue/evport/select

       a.这些多路复用函数可以同时监听多个FD的可读可写情况

       b.redis会优先选择时间复杂度O(1)的函数,也会用select保底

       c.Reactor模式

 1.3.3 redis value 的五大基本数据类型

a.String
1)介绍:

最基本的数据类型,二进制安全,可存储512M,可以保存agv图片,序列化对象等

2)常用命令

set :set  name "redis"

get : get name

incr 应用场景

  计数器: 当前日期的字符串作为key,统计每日访问次数

  作用:让数字类型的value +1

3)底层结构(简单动态字符串SDS)

a.常用属性

   free:记录buf中未使用字节的数量

   len:SDS保存的字符串长度

   char[] buf:保存字符串

b.与C字符串的区别

   SDS获取字符串长度复杂度更低,只需查看len即可

   二进制安全,SDS的API会以处理二进制的方式来处理SDS存放在buf数组里的数据

   API安全,不会造成绝缓冲区溢出

   空间预分配及字符串缩短时的惰性空间释放可减少修改字符串长度时所需的内存重分配次数

   兼容部分C字符串函数

b.hash
1)介绍

String类型的field-value 映射表

2)常用命令

hmset:hmset lilei name "lilei" age 26 title "senior

hget:hget lilei age-------26

hset:hset lilei title "pricipal"

3)底层数据结构

dict+zipList

a.字典dict (字典的常用属性,包含以下几个)

1)type:type属性是一个指向dictType结构的指针,每个dictType结构保存了一簇用于操作特定类型键值对的函数

2)privdata:privdata属性保存了需要传给那些类型特定函数的可选参数

3)哈希表数组 ht:

    ht属性是一个包含两个项的数组,数组中的每个项都是一个dictht哈希表,ht[1]只有在对ht[0]哈希表进行rehash操作时使用,rehash会将将ht[0]中所有键值对rehash到ht[1]中,然后释放ht[0],将ht[1]作为新的ht[0]

   dictht哈希表 结构类似于hashMap,是一个数组+链表的结构,数组的每个元素都是一个哈希表节点dictEntry,不但包含了键值对,也有指向下一个节点的指针,所以是个链表结构

注意:字典结构的应用,除了哈希键底层实现外,由于redis的键值对,本身也是一个hash表,所以Redis数据库底层实现也是字典。

b.zipList (压缩列表是列表键和哈希键的底层实现之一)

c.list
1)介绍:

列表,按照String元素插入顺序排序

2)命令

lpush:lpush mylist aaa;lpush mylist bbb

lrange:

   lrange  mylist 0 10------- bbb aaa

   后进先出,类似栈stack

   后进先出,可以实现最新消息排行榜的功能

lpop:

   rpush mylist aaa;rpush mylist bbb

   lpop mylist----aaa

   使用Rpush,lpop,可实现先进先出,可实现队列

3)底层数据结构

a.双向链表

   1)双端 

     链表节点带有prev和next指针

   2)无环

     表头节点的prev指针和表尾节点的next指针都指向NULL,对链表的访问以NULL为终点

   3)带表头指针和表尾指针

      list对象包含head指针和tail指针直接指向表头和表尾的ListNode对象

   4)带链表长度计数器

      获取链表长度时无需遍历

   5)多态

      链表节点使用void*指针来保存节点值,可保存不同类型的值

b.压缩列表zipList

   当一个列表键值包含少量列表键,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现

   压缩列表是由一系列特殊编码的连续内存块组成的顺序型数据结构,内存空间连续类似数组

d.set
1)介绍

String元素组成的无序集合,通过哈希表实现,不允许重复

2)命令

sadd:sadd myset 111;sadd myset 222

smembers:smembers myset

可以将微博中的 关注的人,粉丝 存在不同的集合,redis的set提供了交集,并集,差集的操作。

3)底层数据结构

a.字典:元素是字典中的key,value同为null

b.intset

1)场景:只有当数据全是整数值,而且数量少于512个时,才使用intset,intset是一个由整数组成的有序集合,因为是有序的可以进行二分查找

2)结构:

encoding:contents数组中元素的类型,有 INTSET_ENC_INT16、INTSET_ENC_INT32 和 INTSET_ENC_INT64 三种,分别表示contents数组中元素类型为 int16_t(16位二进制)、int32_t 和 int64_t 类型

length:记录了整数集合包含的元素数量

contents:整数集合的每个元素都是contents数组的一个数组项,各个项在数组中按值的大小从小到大有序地排列,数组中不包含重复项。

e.sorted set(zset)
1)介绍

string有序集合,每个成员都会关联一个分数,通过分数来为集合中的成员进行排序,成员不可重复,但分数可以

2)命令

zadd:zadd myzset 3 abc; zdd myzset 2 adb

zrangebyscore:zrangebyscore myzset 0 10----adb abc

分数越小约往前排

3)应用

延迟队列:可以把score当作权重,实现根据权重处理消息的功能,权重约小,任务约先执行

4)底层数据结构

a.跳跃表SkipList

(1)节点 zskiplistNode 数据结构

   层

     a.每个节点都会维护一个层,层本身是一个数组结构,数组中的每个元素 包含了前进指针与跨度两个属性

     b.前进指针是一个指向表尾方向的前进指针,用于从表头向表尾方向访问节点,前进指针只能指向下一个节点的同一层。

     c.跨度用于记录两个节点之间的距离,指向NULL的所有前进指针的跨度为0

     d.插入每个节点时分配的层数组的元素个数是随机的,这样不会影响到其他节点层数的变更,只需要修改指针指向即可

  后退指针

     后退指针用于从表尾向表头方向访问节点,每次只能后退一个节点

  分值

     一个double类型的浮点数,所有节点都按照分值从小到大排序,多个节点可以包含相同的分值

  成员 

     一个指针,指向一个字符串对象,该字符串对象保存着一个SDS值,成员对象必须是唯一的

(2)跳跃表结构     

  header和tail指针分别指向跳跃表的表头和表尾节点

  level属性记录层数最高的几点的层数量

  length属性记录节点的数量

(3)跳跃表按 score 从小到大保存所有集合元素,查找时间复杂度为平均 O(logN),最坏 O(N) 。字典则保存着从 member 到 score 的映射,这样就可以用 O(1)的复杂度来查找 member 对应的 score 值

b.zipList

(1)ziplist的存储空间连续且ziplist 内的集合元素按 score 从小到大排序

(2)元素数量小于128,所有元素长度小于64

1.3.4 高级数据类型

a.hyperLogLog

用于计数

b.Geo   

支持存储地理位置信息

1.3.5 常用命令

a.keys pattern

作用:查找所有符合给定模式pattern的key

问题:当key的数量过多,对于内存的消耗和redis服务都是隐患,会阻塞redis

b.scan cursor [Match pattern] [Count count]

  无阻塞的提取出指定的key 列表,每次执行只返回少量元素

  基于游标的迭代器,需要基于上一次的游标延续迭代,以0作为游标开始一次新的迭代,当命令返回游标0,表示完成了遍历

  scan 0 match K1* count 10

1)"11534336" 第一个是返回的游标值,每次返回的游标值不一定是递增的

2)"K1782321" "K123827189"

符合pattern的key 会被返回,注意:count 是10,但结果不一定会返回10个,即使第一次返回没有10个,第二次调用scan,仍然可能有值

1.3.6应用场景

a.分布式锁
1)简介:

分布式锁是控制分布式系统或不同系统之间 共同访问共享数据时 锁的实现

2)分布式锁特性

互斥性/安全性/避免死锁/容错

3)实现

a.SETNX key value

如果key不存在,则创建并赋值,返回1,如果key存在,不会操作,并返回0

时间复杂度为O(1)

b.EXPIRE key seconds

设置key的生存时间,当key过期(生存时间为0),会自动删除

注意:单纯使用上述两个命令,会违背原子性,导致程序有风险,所以,一般分布式锁会用以下命令

c.SET key value [EX seconds] [PX millisenconds] [NX|XX]

EX seconds :设置健的过期时间为seconds 秒

PX millisenconds:设置健的过期时间为millisenconds 毫秒

NX:只有健不存在时,才会对健进行设置操作

XX:只有健已存在,才会对健进行设置操作

SET成功时,会返回OK,否则返回Nil

4)程序问题

a.将释放锁的代码放在finally中,导致A线程释放了B的锁。

    具体场景:线程A在执行了一半时间到了释放了锁,但A未执行完,此时B获取了锁,这时A执行完了,去执行finally释放锁,导致B的锁被释放

    避免:增加唯一请求标识requestId,jedis在释放锁的时候,对比requestId,保证A不会释放B的锁

b.如果锁已经超时了,但是线程还没执行完任务该如何处理

    避免:redission看门狗机制,提供了续锁的实现

c.另一个线程获取锁失败会直接返回吗

     避免:redission 实现了自旋的机制,可以传入一个锁等待的时间

b.异步队列
1)介绍:

以队列数据结构为基础的一个实体,实时性要求不高,且比较耗时的任务,可通过异步的方式处理,是队列的最佳应用场景,

2)场景:

异步发送邮件:账户注册时的激活邮件,发邮件的步骤是不需要实时发送的,发送邮件本来就是一个耗时的操作(需要调用第三方smtp服务器)。可以向队列中存放一条消息,而消费者一进程直在后台运行,不断的去轮训队列中的消息,并取出达到执行条件的,根据消息配置,执行任务,如果成功,则销毁这条消息,继续轮训,如果失败,则重试,直到达到重试次数。这个期间内,用户和程序可以做别的操作,达到异步的效果

高并发点赞:在高并发的情况下,很容易造成数据库连接数占满,导致整个网站响应缓慢,如何解决数据库的压力,一般就是两种方案,一是提高数据库本身的能力(如增加连接数,读写分离等),第二种方案,释放数据库的压力,将压力转移到缓存里面。对于点赞来说,我们将首次点赞请求投递到消息队列里面,后续的点赞请求可以将消息合并,即只更新点赞数,不产生新的任务,此时有个进行再不断的轮训消息队列,将点赞消息消耗,并将值更新到数据库里面,这样就有效的降低了数据库的压力,大大提高了效率,降低了负载

3)优点

对比通常消息中间件,如  Rabbitmq 和 Kafka ,redis使用简单,比较轻量,适合一些简单的异步场景。如果不需要消息队列的一些高级特性,对可靠性没有极致的要求,可用redis

4)应用

a.rpush,lpop

   使用List作为队列,RPUSH生产消息,LPOP消费消息

   缺点:没有等待的机制,如果队列里没值,也会执行消费的操作,可以用sleep的机制去调用lpop重试

b.blpop

  BLPOP key [key ...] timeout:阻塞直到队列有消息或超时,缺点:只能消费一次

c.pub/sub:主题订阅者模式

  发送者(pub)发送消息,订阅者(sub)接收消息

  频道,即topic,订阅者可以订阅任意数量的频道

     订阅频道subscribe myTopic

     在频道发送消息:publish myTopic "Hello"

  缺点:消息的发布无状态,无法保证可达

c.延时队列
1)场景

可实现一些延时任务的需求场景,比如十分钟后订单自动取消

2)应用

使用 zset(sortedset)命令,用设置好的时间戳作为score进行排序,消费者线程利用 zrangebysocre 查询符合条件的所有待处理的任务,通过循环查询队列任务,通过score值来判断任务执行的时间是否大于了当前系统的时间

1.3.7 常见问题  

a.缓存雪崩:

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力

解决:大量key同时过期,redis的线程在删除key时,可能会导致服务器卡顿,所以建议在设置过期时间时,加上随机值

b.缓存穿透

key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息

解决:增加数据校验,过滤非法数据

c.缓存击穿

key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮

解决:热点数据,不设置过期时间;使用互斥锁

1.3.8 持久化

a.RDB(快照)持久化

特定间隔,保存某个时间点的全部内存数据

1)命令

save:主进程执行,save指令执行时,会阻塞redis的服务进程,直到rdb文件创建完毕,时间较长。

bgsave:fork出一个子进程创建RDB文件,不阻塞主进程

lastsave:返回上次成功执行save成功的时间

2)触发方式

a.redis.conf 中存储策略save minutes number

   minutes秒内有number次写入,就进行一次备份,执行方式为bgsave

b.主从复制,主节点自动触发

c.执行debug reload

d.执行shutdown且没有开启AOF持久化

3)特点

缺点

    a.快照持久化,每次会持久化全量数据,而不是增量持久化,当数据量很大时,会由于I/O严重影响性能

    b.快照一定时间做一次,可能会因为redis挂掉,丢失当前时间至最近一次快照期间的数据。

优点

    全量数据快照,文件小,恢复快

b.AOF(Append-Only-File)持久化
1)保存写状态

记录所有除了查询之外的所有变更数据库状态的指令

以append的方式追加到AOF文件中(增量)

2)触发方式

redis.conf中appendonly 设为yes(默认为no)

appendfsync

   always-只要发生变化就写入aof

   everysec-每隔一秒

   no-缓存区填满后,写入aof

3)aof文件

日志重写

      a.调用fork(),创建一个子进程

      b.子进程把新的aof写到一个临时文件中,不依赖原来的aof文件

      c.主进程将新的变动同时写到内存与原来的aof中

      d.子进程完成后,主进程往新的aof同步增量变动

      e.将新的aof替换旧的aof

bgrewriteaof 手动触发

4)特点

优点:可读性高,适合保存增量数据,数据不易丢失

缺点:文件体积大,恢复时间长,会膨胀需要重写

c.RDB-AOF混合持久化

bgsave做镜像全量持久化,aof做增量持久化

1.3.9 同步机制与集群

a.主从同步
1)全同步

Slave发送sync命令到Master

Master启动一个后台进程,将redis中的数据快照保存到文件中

master将保存数据快照期间接收到的指令缓存起来(增量数据)

Master完成写文件操作后,将文件发送给Slave,Slave使用新的RDB文件替换掉旧的RDB文件

Master将这期间收集的增量写命令发送给Slave端

2)增量同步

master接收到用户的操作,判断是否需要传播到Slave

将操作记录追加到AOF文件

Master将操作传播到其他Slave:1.对齐主从库2.将指令写入到响应缓存中

将缓存中的数据发送给Slave

b.redis Sentinel哨兵

监控:检查主从服务器是否运行异常

提醒:通过api向管理员或其他应用程序进行通知

自动故障迁移:主从切换。主服务器宕机后,将一台从服务器升级

c.流言协议Gossip
d.集群

一致性hash算法(hash环)

2.mongoDB

2.1简述

a.关系型数据库中,数据是以表单为媒介进行存储的,每个表单均拥有纵向的列和横向的行

b.而mongoDB本身也是一种非关系型数据库,将数据存储为一个文档,数据结构由键值(key=>value)对组成,文档类似于json对象的格式

2.2索引

mongoDB的索引实现与innodb类似,也是使用多路查找树(B+树)

2.2.1索引分类

a.单字段索引

可对某个field创建单字段索引,其能加速对field字段的各种查询请求,是最常见的索引形式,MongoDB默认创建的id索引也是这种类型。

b.复合索引

多个字段联合创建索引,先按第一个字段排序,第一个字段相同的文档按第二个字段排序,依次类推

c.多key索引

当索引的字段为数组时,创建出的索引称为多key索引,多key索引会为数组的每个元素建立一条索引

d.文本索引(Text Index)

能解决快速文本查找的需求,比如有一个博客文章集合,需要根据博客的内容来快速查找,则可以针对博客内容建立文本索引。

e.hash索引

是指按照某个字段的hash值来建立索引,目前主要用于MongoDB Sharded Cluster的Hash分片,hash索引只能满足字段完全匹配的查询,不能满足范围查询等。

f.地理位置索引(Geospatial Index)

能很好的解决O2O的应用场景,比如『查找附近的美食』、『查找某个区域内的车站』等

g.其他

1)唯一索引

2)部分索引(只针对符合某个特定条件的文档建立索引)

2.3特点

a.优点

  相比传统的关系型数据库,它非常容易被扩展

  适合文档类型的存储与查询

  速度快

b.缺点

  旧版本不支持事务;比较耗费存储空间

c.可用于后端数据库,也可用于缓存数据库

3.全文检索

3.1简述

非结构化的数据检索,先建立索引,再对索引进行搜索文档的过程就叫全文检索(Full-text Search)

3.2场景

搜索引擎(对算法、数据结构要求较高)

站内搜索(直接使用ElasticSearch基本可以满足)

系统文件搜索

3.3应用

3.3.1 Lucene

Lucene是一个基于java开发的优秀的开源搜索库,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而只是一个全文检索引擎的架构,专注于底层

3.3.2 solr

使用java实现的一个web应用,可以使用rest方式的http请求,进行远程API的调用

3.3.3Elastic Search

可以使用rest方式的http请求,进行远程API的调用。

ES底层使用了Lucene来构建索引

3.3.4对比

solr与ES都是基于Lucene的封装的分布式搜索引擎,通过简单的RESTful API来屏蔽了Lucene的复杂性,从而让全文搜索变得简单

ElasticSearch与Solr对比,ES的搜索性能会优于solr,尤其是在数据量不断增大后,而且在实时更新索引的场景下,solr还有可能发生io阻塞。所以es比solr更快

3.4全文检索步骤

3.4.1如何创建索引(索引库)

a.收集数据

收集数据,创建文档(document)对象

b.分析文档

   1)分析文档主要是对Field域进行分析,分析文档的目的是为了索引

   2)分词组件(Tokenizer)

       内容:1.将Field域中的内容进行分词(不同语言有不同的分词规则)

                2.去除标点符号。

               3.去除停用词(stop word)

       分词使用的分词器以配置mapping时指定的为准,默认使用standard分词器,对于中文分词来说,一般建议使用ik_smart或ik_max_word分词器

       经过分词(Tokenize)之后得到的结果成为词元(Token)。

    3)语言处理组件(Linguistic Processor)

        将得到的词元(Token)传给语言处理组件(Linguistic Processor),语言处理组件(linguistic processor)主要是对得到的词元(Token)做一些同语言相关的标准化处理

        内容:1.大小写转换

                2.将单词缩减为词根形式,如“cars”到“car”等

                3.将单词转变为词根形式,如“drove”到“drive”等

        语言处理组件(linguistic processor)的结果称为词(Term)

c.索引创建

    1)说明:将得到的词(Term)传给索引组件(Indexer),构建索引库,最终的索引结构是一种倒排索引结构也叫反向索引结构

    2)索引组件的工作:

       1.创建Term字典-构建term与document的映射关系

       2.排序Term字典

       3.合并Term字典:合并相同的词(Term)成为文档倒排(Posting List)链表

    3)创建的索引被称为倒排索引

       倒排索引是为了解决非结构化数据的检索问题而产生的

       倒排索引先将文档中包含的关键字全部提取出来,然后再将关键字与文档的对应关系保存起来,最后再对关键字本身做索引排序。用户在检索某一关键字时,可以先对关键字的索引进行查找,再通过关键字与文档的对应关系找到所在文档

3.4.2索引库搜索

1)说明:得到用户的查询请求,搜索创建的索引,然后返回结果的过程

2)lucene查询语法:

域名:关键字

域名:[min to max]

3)步骤

1.根据关键字,进行分词,根据分词查询到的文档链表

2.文档链表的顺序是根据相关度打分排序的

3.5 ES基本概念

3.5.1索引(Index)

ES存储数据的基本单位是索引,ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比mysql,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。

3.5.2类型(Type)

类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义

在索引中,可以定义一个用于存储用户数据的类型,一个存储日志数据的类型,类比MySQL,类型相当于“表”

3.5.3文档(Document)

一个Document文档中包括多个域(Field),基于JSON格式进行表示

数据库中一条记录当成一个Document,一列当成一个Field

3.5.4映射(Mapping)

ES中,所有的文档在存储之前都要首先进行分析。用户可根据需要定义如何将文本分割成token、哪些token应该被过滤掉,以及哪些文本需要进行额外处理等

3.5.5 ES 是如何实现分布式

每个索引可以拆分成多个 shard ,每个 shard 存储部分数据

    a.数据量增大时,支持横向扩展

    b.提高性能

数据备份,每个 shard 都有一个 primary shard ,负责写入数据,但是还有几个 replica shard 。 primary shard 写入数据之后,会将数据同步到其他几个 replica shard 上去

多台机器上启动多个 ES 进程实例,组成了一个 ES 集群,多个节点,会自动选举一个节点为 master 节点,这个 master 节点其实就是干一些管理的工作的,比如维护索引元数据、负责切换 primary shard 和 replica shard 身份等。要是 master 节点宕机了,那么会重新选举一个节点为 master 节点,若是非master节点宕机,但该节点有primary shard,master会切换其他机器上的replica shard 作为primary shard

3.5.6 ES性能优化

优化filesystem cache

   es 里写的数据,实际上都写到磁盘文件里去了,查询的时候,操作系统会将磁盘文件里的数据自动缓存到 filesystem cache 里面去,es 的搜索引擎严重依赖于底层的 filesystem cache ,你如果给 filesystem cache 更多的内存,尽量让内存可以容纳所有的 idx segment file 索引数据文件,那么你搜索的时候就基本都是走内存的,性能会非常高

   es中尽量只存放用来搜索的字段。搜索到之后再去其他数据库进行检索。

3.5.7 ES数据同步

实时性要求不高:通过定时脚本,去mysql中读取数据,同步到ES

实时性要求高:canal 监控binlog,canal会模拟MySQL主库和从库的交互协议,从而伪装成MySQL的从库,然后向MySQL主库发送dump协议,MySQL主库收到dump请求会向canal推送binlog,canal通过解析binlog将数据同步到其他存储中去

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值