深刻解读阿里云数据库POLARDB核心功能会话读一致性

POLARDB架构

咱们知道,POLARDB是一个由多个节点构成的数据库集群,一个主节点,多个读节点。对外默认提供两个地址,一个是集群地址,一个是主地址,推荐使用集群地址,由于它具有读写分离功能能够把全部节点的资源整合到一块儿对外提供服务。数据库

image.png | left | 827x520

MySQL读写分离解决和引入的问题

用过MySQL的都知道,MySQL的主从复制简单易用,很是流行,经过把主库的Binlog异步地传输到备库并实时应用,一方面能够实现高可用,另外一方面备库也能够提供查询,来减轻对主库的压力。架构

image.png | center | 400x279.445727482679

虽然备库能够提供查询,但存在两个问题,一是主库和备库通常提供两个不一样的访问地址,应用程序端须要选择使用哪个,对应用有侵入。二来MySQL的复制是异步的,即便是半同步也没办法作到100%强同步,所以备库的数据并非最新的,有延迟,没法保证查询的一致性。app

为了解决第一个问题,咱们引入了读写分离代理,以下图,对应用程序很是友好。通常的实现是,代理会伪形成MySQL与应用程序创建好链接,解析发送进来的每一条SQL,若是是UPDATE、DELETE、INSERT、CREATE等写操做则直接发往主库,若是是SELECT则发送到备库。负载均衡

image.png | left | 827x326

可是第二个问题——延迟致使的查询不一致——仍是没有解决,使用时,就不可避免地会遇到备库SELECT查询数据不一致的现象(由于主备有延迟)。MySQL负载低的时候延迟能够控制在5秒内,但当负载很高时,尤为是对大表作DDL(好比加字段)或者大批量插入的时候,延迟会很是严重。异步

POLARDB读写分离的会话读一致性

POLARDB是读写分离的架构,传统的读写分离都只提供最终一致性的保证,主从复制延迟会致使从不一样节点查询到的结果不一样,好比一个会话内连续执行如下QUERY:spa

INSERT INTO t1(id, price) VALUES(111, 96);
UPDATE t1 SET price = 100 WHERE id=111;
SELECT price FROM t1;代理

在读写分离的下,最后一个查询的结果是不肯定的,由于读会发到只读库,在执行SELECT时以前的更新是否同步到了只读库时不肯定的,所以结果也是不肯定的;由于有这个问题,因此就要求应用程序去适应最终一致性,而通常的解决方法是: 将业务作拆分,有高一致性要求的请求直连到主库,能够接受最终一致性的部分走读写分离;显然这样会增长应用开发的负担,还会增大主库的压力,影响读写分离的效果;code

为了解决这个问题,在POLARDB中咱们提供了会话一致性或者说因果一致性的保证,会话一致性即保证同一个会话内,后面的请求必定可以看到此前更新所产生版本的数据或者比这个版本更新的数据,保证单调性,就很好的解决了上面这个例子里的问题;blog

实现原理

image.png | left | 827x470

在POLARDB的链路中间层作读写分离的同时,中间层会track各个节点已经apply了的redolog位点即LSN,同时每次更新时会记录这次更新的位点为Session LSN, 当有新请求到来时咱们会比较Session LSN 和当前各个节点的LSN,仅将请求发往LSN >= Session LSN的节点,从而保证了会话一致性;表面上看该方案可能致使主库压力大,可是由于POLARDB是物理复制,上一篇已详细介绍过,速度极快,在上述场景中,当更新完成后,返回客户端结果时复制就同步在进行,而当下一个读请求到来时主从极有可能已经完成,而后大多数应用场景都是读多写少,因此经验证在该机制下即保证了会话一致性,也保证了读写分离负载均衡的效果;资源

相关文章:

做者: 乙休
原文连接 本文为云栖社区原创内容,未经容许不得转载。

相关文章
相关标签/搜索