`
huangyongxing310
  • 浏览: 476231 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

ES数据同步方案

阅读更多
//===============================================================
ES数据同步方案
1.同步双写
数据写到mysql时,同时将数据写到ES,实现数据的双写。
优点:业务逻辑简单。
缺点:硬编码,业务强耦合,性能较差,代码的侵入性太强

2.异步双写(MQ方式)(程序到MQ,MQ再到MYSQL和ES)
改为写MQ,不直接写ES
优点:性能高(由于MQ的性能基本比mysql高出一个数量级);不存在丢数据问题
缺点:硬编码,业务强耦合,代码的侵入性太强,延时


3.异步双写(Worker方式)(定时任务)
让该程序按一定的时间周期扫描指定的表,把该时间段内发生变化的数据提取出来;逐条写入到ES中。
优点:不改变原来代码,没有侵入性、没有硬编码;没有业务强耦合;
缺点:时效性较差

4.Binlog 同步方式
利用mysql的binlog来进行同步
优点:没有代码侵入、没有硬编码;原有系统不需要任何变化,没有感知;性能高;业务解耦,不需要关注原来系统的业务逻辑。
缺点:构建Binlog系统复杂;也像方案二,存在MQ延时的风险



//===============================================================
MYSQL同步方式,主从复制、半同步复制和主主复制
MySQL数据库的复制需要启动三个线程来实现:
其中1个在主服务器上,另两个在从服务器上。当发出START SLAVE时,从服务器创建一个I/O线程,以连接主服务器并让它发送记录在其二进制日志中的语句。主服务器创建一个线程将二进制日志中的内容发送到从服务器。该线程可以识别为主服务器上SHOW PROCESSLIST的输出中的Binlog Dump线程。从服务器I/O线程读取主服务器Binlog Dump线程发送的内容并将该数据拷贝到从服务器数据目录中的本地文件中,即中继日志。第3个线程是SQL线程,是从服务器创建用于读取中继日志并执行日志中包含的更新。
————————————————
https://blog.csdn.net/weixin_35794185/article/details/113158779

异步复制
通常没说明指的都是异步,即主库执行完Commit后,在主库写入Binlog日志后即可成功返回客户端,无需等等Binlog日志传送给从库,一旦主库宕机,有可能会丢失日志。

半同步复制
半同步启动需要主从两端都需要加载安装各自对应的semi模块
而半同步复制,是等待其中一个从库也接收到Binlog事务并成功写入Relay Log之后,才返回Commit操作成功给客户端;如此半同步就保证了事务成功提交后至少有两份日志记录,一份在主库Binlog上,另一份在从库的Relay Log上,从而进一步保证数据完整性;半同步复制很大程度取决于主从网络RTT(往返时延),以插件 semisync_master/semisync_slave 形式存在。
半同步复制是介于全同步复制和全异步复制之间的一种,主库只需要等待至少一个从库节点收到并Flush Binlog到Relay log文件即可,主库不需要等待所有从库给主库反馈。

全同步
全同步是指当主库接收到客户端的一个事务请求,所有的从库都执行了该事务才返回给客户端。

因为要等待所有从库执行完事务,主库才将结果返回给客户端,所以全同步复制的性能必然受到严重影响,即完成一个事务的时间被拉长,性能降低。


//===============================================================
redis主从复制原理
主从复制,直观的做法是主节点产生一份数据的快照发送给从节点,以快照数据为基准,将之后增量的数据变更同步给从节点,如此就能保证主从数据的一致。总体来看,主从复制一般包含全量数据同步、增量同步两个阶段。

全量数据同步:主节点产生一份全量数据的快照,即RDB文件,并将此快照发送给从节点。且从产生快照时刻起,记录新接收到的写命令。当快照发送完成后,将累积的写命令发送绐从节点,从节点执行这些写命令。此时基准已经建立完成。
命令传播:全量数据同步完成后,主节点将执行过的写命令源源不断地发送给从节点,从节点执行这些命令,保证主从节点中数据有相同的变更,如此保证主从节点数据的一致。

1、主从关系建立后,从节点向主节点发送一个 SYNC 命令请求进行主从同步。
2、主节点收到 SYNC 命令后,执行 fork 创建一个子进程,子进程将所有的数据编码存储到 RDB(Redis Database) 文件中,这就产生了数据库的快照。
3、主节点将此快照发送给从节点,从节点接收快照并载入。
4、主节点接着将生成快照、发送快照期间积压的命令发送给从节点。
5、此后,主节点源源不断地新执行的写命令同步到从节点,从节点执行传播来的命令,命令执行后,从库中的数据也就得到了更新。如此,主从数据保持一致。需要说明的是,命令传播存在时延的,所以任意时刻,不能保证主从节点间数据完全一致。

以上就是 Redis 主从复制的基本原理,很简单很容易理解,但存在一些不美好的地方:
fork 耗时过长,阻塞主进程
执行fork 时候,需要拷贝大量的内存页表,这是一个耗时较多的操作,尤其当内存使用量较大的时候。组内同学曾做过测试,内存占用 10GB 时,fork 需要消耗 100 多毫秒。fork 的时候主进程阻塞 100 多毫秒,这对 Redis 而言,实在太长了。另外,fork 之后,如果主库中有不少的写入,那么由于写时复制机制,会额外消耗不少的内存,还会增大响应时间。
如果主从间网络闪断怎么办

如果网络故障,连接断开,主节点无法继续传播信息至该从节点。之后网络恢复,从节点重新连接上主节点后,主节点不能再继续传播新接收到的信息了,因为从节点已经漏掉了一些命令。此时,从节点需要从来,再次执行全部的同步过程,
网络闪断是常发生的事情,闪断期间主节点中可能只写入了比较少的数据,但就因为这很少的一部分数据,需要让从节点进行一全量同步。这种做法是非常低效的,该如何解决这问题


Redis部分重同步
Redis 2.8 版本后,引入了部分同步。它在主节点中维护了一个复制积压缓冲区,命令一方面会传播到从节点,另外还会记录在这个缓冲区中。保持所有的命令是不必要的,Redis 中使用了一个环形的缓冲区,这样就可以只保留最近的一些命令了。

有了部分同步,网络闪断后就可以避免全量同步了。但是因为主节点只能保留最近的部分命令,保存多少取决于复制积压缓冲区的大小。如果从节点断开时间过长,或者断开期间主节点新执行的写命令足够多,漏掉的命令就无法全部保存到复制积压缓冲区中了。加大复制积压缓冲区可以尽可能多地避免全量同步,但这同时会造成额外的内存消耗。

部分同步消耗了部分内存来保存最近执行的写命令,避免闪断后的全同步,这是很直观、很容易想象的解决方案。这种方案很好,它是否还存在其他问题呢?考虑以下问题:
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics