OneProxy :: 更加适用于MySQL集群的基于分库分表信息的负均均衡策略。

假设数据库里有100GB的用户表,会被频烦地访问到,比如每次登录或每次交易时都要访问好几次,虽然一定会有缓存来加快,但也得考虑到缓存失效的情况,大量的请求还是会落回到数据库中,以防万一。当使用一主多备的情况下,或者使用多主集群(MariaDB Galera Cluster / Percona XtraDB Cluster)时,应当如何来做负载均衡呢? 以读流量为主时,最好的访问策略是单点写入多点读取的读写分离架构是非常适用的。

oneproxy_read_write_split_arch

假设使用一主四备的架构,并且每台数据库机器的内存只有32GB,如果流量随机均衡地分发到不同的节点,等于所有的备库上都需要访问全部的100GB数据,由于数据量比内存要大将近四倍,因此有可能会有较大的IO压力;如果每台备库只访问四分之一的数据,四台备库在一起提供百分之百的数据访问,则可以全部在内存里命中,是否可以设计这样的分流逻辑呢?当然可以!

oneproxy_shard_load_balance

可以使用OneProxy的分库分表功能来将用户表切分成四份或八份,或更多的切片,然后可以设置按照分片号来进行流量转发,就会得到如上图所示的效果,每一台备库承担一个分片表的查询流量,每个备库的内容刚好可以存放下一个分片的数据,就不会有严重的IO问题了。在公有云上使用这个策略,可以帮助你节约升级的成本,只需要在OneProxy将策略定义为“read_shard”即可,前提是你得使用OneProxy来做单一实例内部的水平分表。

......
proxy-master-addresses.1  = 172.30.12.X:3306@user
proxy-slave-addresses.1   = 172.30.12.X:3306@user
proxy-slave-addresses.2   = 172.30.12.X:3306@user
proxy-slave-addresses.3   = 172.30.12.X:3306@user
proxy-slave-addresses.4   = 172.30.12.X:3306@user
......
proxy-group-policy.1      = user:read_shard
......

假设你将系统布署在集群上,比如Percona XtraDB Cluster或者官方的Group Replication技术(还在Beta中),集群中每个节点都可以用来承担写入流量,如果合理地转发流量呢?考虑行级冲突的情况下会影响性能,最好的办法可能是将写流量集中到一个节点上,或者和前面的例子类似,使用分库分表功能将表做切片,然后按分片的编号来将写流量分流到不同的节点上,以保证不会有行级更新冲突发生。仍旧以前面的会员表为例子,将集群的所有节点都配置成主库类型,然后将分流策略配置成“write_shard”即可。

......
proxy-master-addresses.1  = 172.30.12.X:3306@user
proxy-master-addresses.2  = 172.30.12.X:3306@user
proxy-master-addresses.3  = 172.30.12.X:3306@user
proxy-master-addresses.4  = 172.30.12.X:3306@user
......
proxy-group-policy.1      = user:write_shard
......

通过这两种基于分片信息的策略“read_shard”和“write_shard”,你可以很容易地创建一个非常强大的数据库集群,以快速支撑业务的高速发展。