这种模型非常地简单,部署起来也非常的简单,并且,由于我们的业务系统都是读写同一个数据库,所以,在正常情况下,没有存在数据不一致的问题。当然,缺点也是非常地明显,那就是从数据库完全沦为冷备,除非在主库无法使用的情况下,否则从数据库只能是一个备胎。造成极大地浪费,另外一个方面,主从之间同步是有延迟的,在主备切换的时候,可能会有少量的数据丢失。
另外一个问题,上述的主备模型只能够增加系统的容灾,不仅不能提升性能,反而因为主库需要同步数据到备库,会对性能有所消耗。那么,我们为什么不把备库利用起来呢?于是,有了数据库读写分离的方案,在主库上进行数据写入,在从库上进行数据读取,就好比有一条马路,原来机动车与非机动车都一起行驶,相当混乱,于是我们规定一个车道为非机动车道,行人在上面行走,而机动车只能在机动车道行驶,从而保证了马路的秩序。
既然有了多个数据库,那么我们自然就会涉及到一个问题,数据库的同步,我们以Mysql为例,介绍几种常见的数据库同步方式。
全同步复制:指当主库执行完一个事务,之后发指令给所有的从库,让从库都执行相同的指令,执行成功之后,才返回给客户端,指令执行成功。这么做的优点是可以保证数据的强一致性,不过很明显,全同步的效率太低了。因为所有的请求都需要双倍的写入时间,假如原本一个写请求需要30毫秒,现在最少需要60毫秒了。这种只适合多读极少写要求数据强一致的业务场景。
异步复制:MySQL默认的复制即是异步复制的,主库在执行完客户端提交的事务后会立即将结果返给给客户端。主库再负责把对应的命令分发给从库进行执行,很显然,这个会造成可能主库已经写完了,但是从库的数据还没有同步,读到的可能是旧数据。另外一方面,如果某个时间主DB宕机了,那么从库还没有同步到最新的数据。
半同步复制:介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。这是一个相对折衷的方案,我们来看看这个东西是怎么实现。
我们都知道,数据库在计算机应用中有着举足轻重的作用。为什么我们需要数据库,这个问题并不难回答,因为我们的很多数据需要进行持久化,并且需要高效地进行存储,并且可以快速读取,数据要保持准确,不同机器也要保持一致性。
我们都知道,是机器就可能会出问题,并且还可能伴随着网络、电网等多种不可抗力因素,这年头,像支付宝被挖断光纤的事情,几乎每年就会出现好几起。今天,我们来聊一聊数据库的一些事情。
我们常常使用分布式,也就是多机方案来解决上述问题,最简单的方法,我们可以使用一台备机,将主数据库的数据同步过去,这个时候,所有的业务系统仍然读写主数据库,从数据库只做冷备处理。
业务方提交一个写操作给数据库,数据库写完记录之后,commit成功,然后像所有的从数据库发起写bin log的请求,由于写bin log都是追加写文件,所以速度非常快,并且几乎没有失败,写完就返回,消耗的时间几乎为零,相当于一次写操作只增加一次TCP往返的时间。
事实上,从主库返回成功,到备库异步提交成功,还是有一定的时间差,不过这个时间相对于异步复制,已经大大减少了。即便如此,我们也要做好相对应的监控,同时也要避免写完数据立即读取数据这样的业务场景。一般我们也有3种方法。
参数冗余,我们在写完数据库之后,再进行别的操作的时候,这个时候我们通常会传一个ID,让下游系统自己查询,我们可以替换成下发全量的数据,免去下游系统查询的需要。
数据库缓存,我们可以使用缓存,缓存对应的数据,在更新完数据库之后,同时更新缓存,这样,我们就可以避免接下来的查询请求击穿到数据库,在还没有同步到从库的时候查询数据,造成脏数据。
强制读取主库数据对于刚刚更新的数据,我们可以强制更新主库,怎么确认是刚刚更新的数据呢?一般我们会用Redis或者Memcache进行存储一个key最近的变更时间。
以上就是数据库读写分离常见的知识了,接下来我们还会继续讲一讲数据库相关知识。欢迎关注我,后面我们会继续分析。大家共同学习,共同进步。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.