大型网站主从库复制延迟解决方案

像Facebook、开心001、人人网、优酷、豆瓣、淘宝等高流量、高并发的网站,单点数据库很难支撑得住,WEB2.0类型的网站中使用MySQL的居多,要么用MySQL自带的MySQL NDB Cluster(MySQL5.0及以上版本支持MySQL NDB Cluster功能),或者用MySQL自带的分区功能(MySQL5.1及以上版本支持分区功能),我所知道的使用这两种方案的很少,一般使用主从复制,再加上MySQL Proxy实现负载均衡、读写分离等功能,在使用主从复制的基础上,再使用垂直切分及水平切分;或者不使用主从复制,完全使用垂直切分加上水平切分再加上类似Memcached的系统也可以解决问题。

1.优酷的经验 数据库采用水平扩展,主从复制,随着从数据库的增多,复制延迟越来越厉害,最终无法忍受。 最终还是采用数据库的sharding,把一组用户相关的表和数据放到一组数据库上。 使用SSD来优化mysql的I/O,性能提升明显,每块16G,6块SSD做RAID。 数据库的类型选用MYISAM 数据库的拆分策略,先纵向按照业务或者模块拆分。对于一些特别大的表,再采用垂直拆分 根据用户进行分片,尽可能不要跨篇查询。如果确实要跨片查询,可以考虑搜索的方案,先索引再搜索。 分布式的数据库方案太复杂,否掉。

优酷使用的是数据库分片技术,而抛弃了由于数据量的越来越多导致复制延迟的问题。按照user_id进行分片,这样必须有一个全局的表来管理用户与shard的关系,根据user_id可以得到share_id,然后根据share_id去指定的分片查询指定的数据。

假如此表的表名为sharding_manager,如果网站的用户数太多,比如千万级的或甚至更大比如亿级的用户,此时此表也许也会成为一个瓶颈,因为查询会非常频繁,所有的动态请求都要读此表,这时可以用其它的解决方案,比如用Memcached、Tokyo Cabinet、Berkeley DB或其它的性能更高的方案来解决。

具体怎么定位到哪台db服务器,定位到哪个数据库,定位到哪个shard(就是userN,msgN,videoN),优酷网的架构文档中说得不是很仔细,这里只能猜测一下了。

根据优酷的架构图,一共有2台db服务器,每台db服务器有2个数据库,每个数据库有3个shard,这样一共是2 * 2 * 3 = 12个shard。

user_id一般是自增型字段,用户注册的时候可以自动生成,然后看有几台db服务器,假如有m台db服务器,则用 user_id % m便可以分配一台db服务器(例如0对应100,1对应101,以此类推,字段mysql_server_ip的值确定),假设每台服务器有n个数据库,则用user_id % n可以定位到哪个数据库(字段database_name的值确定),假设每个数据库有i个shard,则用user_id % i可以定位到哪个shard(字段shard_id的值确定),这样就可以进行具体的数据库操作了。

user_id share_id mysql_server_ip database_name 101 2 192.168.1.100 shard_db1 105 0 192.168.1.100 shard_db2 108 0 192.168.1.101 shard_db3(或shard_db1) 110 1 192.168.1.101 shard_db4(或shard_db2)

如上述user_id为101的用户,连接数据库服务器192.168.1.100,使用其中的数据库为shard_db1,使用其中的表系列为user2,msg2,video2

如果上述的m,n,i发生变化,比如网站的用户不断增长,需要增加db服务器,此时则需要进行数据库迁移,关于迁移,参见这儿。

因为表位于不同的数据库中,所以不同的数据库中表名可以相同 server1(192.168.1.100) shard_db1 user0 msg0 video0 user1 msg1 video1 ... userN msgN videoN shard_db2 user0 msg0 video0 user1 msg1 video1 ... userN msgN videoN

因为表位于不同的数据库服务器中,所以不同的数据库服务器中的数据库名可以相同 server2(192.168.1.101) shard_db3(这里也可以用shard_db1) user0 msg0 video0 user1 msg1 video1 ... userN msgN videoN shard_db4(这里也可以用shard_db2) user0 msg0 video0 user1 msg1 video1 ... userN msgN videoN

2.豆瓣的经验 由于从主库到辅库的复制需要时间 更新主库后,下一个请求往往就是要读数据(更新数据后刷新页面) 从辅库读会导致cache里存放的是旧数据(不知道这个cache具体指的是什么,如果是Memcached的话,如果更新的数据的量很大,难道把所有更新过的数据都保存在Memcached里面吗?) 解决方法:更新数据库后,在预期可能会马上用到的情况下,主动刷新缓存 不完美,but it works

豆瓣后来改为双MySQL Master+Slave说是能解决Replication Delay的问题,不知道是怎么解决的,具体不太清楚。

3.Facebook的经验

下面一段内容引用自www.dbanotes.net 大量的 MySQL + Memcached 服务器,布署简示: California (主 Write/Read)............. Virginia (Read Only) 主数据中心在 California ,远程中心在 Virginia 。这两个中心网络延迟就有 70ms,MySQL 数据复制延迟有的时候会达到 20ms. 如果要让只读的信息从 Virginia 端发起,Memcached 的 Cache 数据一致性就是个问题。

1 用户发起更新操作,更名 "Jason" 到 "Monkey" ; 2 主数据库写入 "Monkey",删除主端 Memcached 中的名字值,但Virginia 端 Memcached 不删;(这地方在 SQL 解析上作了一点手脚,把更新的操作"示意"给远程); 3 在 Virginia 有人查看该用户 Profile ; 4 在 Memcached 中找到键值,返回值 "Jason"; 5 复制追上更新 Slave 数据库用户名字为 "Monkey",删除 Virginia Memcached 中的键值; 6 在 Virginia 有人查看该用户 Profile ; 7 Memcache 中没找到键值,所以从 Slave 中读取,然后得到正确的 "Monkey" 。 Via

从上面3可以看出,也仍然存在数据延迟的问题。同时master中数据库更新的时候不更新slave中的memcached,只是给slave发个通知,说数据已经改变了。

那是不是可以这样,当主服务器有数据更新时,立即更新从服务器中的Memcached中的数据,这样即使有延迟,但延迟的时间应该更短了,基本上可以忽略不计了。

4.Netlog的经验

对于比较重要且必须实时的数据,比如用户刚换密码(密码写入 Master),然后用新密码登录(从 Slaves 读取密码),会造成密码不一致,导致用户短时间内登录出错。所以在这种需要读取实时数据的时候最好从 Master 直接读取,避免 Slaves 数据滞后现象发生。还好,需要读取实时数据的时候不多,比如用户更改了邮件地址,就没必要马上读取,所以这种 Master-Slaves 架构在多数情况下还是有效的。

本文分享自微信公众号 - nginx(nginx-study)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-04-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据文摘

资源 | 一网打尽成语歇后语,GitHub新华字典数据库

数据库收录了包括14032条歇后语,16142个汉字,31648个成语。下面文摘菌就简单的介绍一下这个数据库。

20500
来自专栏古时的风筝

如何接手一个新项目

2、为技术服务的项目,比如开源中间件项目(dubbo、spring cloud、各种数据库中间件、各种缓存方案等);

18100
来自专栏函数式编程语言及工具

PICE(3):CassandraStreaming - gRPC-CQL Service

  在上一篇博文里我们介绍了通过gRPC实现JDBC数据库的streaming,这篇我们介绍关于cassandra的streaming实现方式。如果我们需要从一...

21800
来自专栏Script Boy (CN-SIMO)

连接远程数据库ORACLE11g,错误百出!

首先,我已经提前在虚拟机上配置了windows2008+oracle11g,为什么用server2008呢?我没有别的,win10做虚拟机觉得不太好,win7镜...

16800
来自专栏云计算D1net

如何避免即将到来的云复杂性危机

云复杂性危机即将爆发。我们每天都向云端添加数百个工作负载,建立新的数据库,添加不同类型的计算和存储,以及添加基于云的网络——并且在不撤下几乎不存在的内部部署的资...

10500
来自专栏函数式编程语言及工具

PICE(2):JDBCStreaming - gRPC-JDBC Service

   在一个akka-cluster环境里,从数据调用的角度上,JDBC数据库与集群中其它节点是脱离的。这是因为JDBC数据库不是分布式的,不具备节点位置透明化...

13200
来自专栏云计算D1net

主动多云成本管理的关键是什么?

如今,很多企业正在转向采用多云。这是为什么?云计算采用者通常引用的关键驱动因素是速度、敏捷性、平台灵活性,以及降低的成本,或者说至少是可预测的成本。

10800
来自专栏云计算D1net

拥抱云计算以人为本

随着企业加速迁移到云,他们获得的不仅仅是效率的提升和一个新的协作工具。在这个云应用的新时代,人们可以为企业云添加各种强大的功能,比如人工智能、区块链、高级分析和...

15500
来自专栏古时的风筝

从实例出发,了解单例模式和静态块

什么是单例模式呢,单例模式(Singleton)又叫单态模式,它出现目的是为了保证一个类在系统中只有一个实例,并提供一个访问它的全局访问点。从这点可以看出,单例...

9700
来自专栏云计算D1net

在多云策略中确保应用程序可迁移性的三种方法

为了保持竞争优势,所有主要的公共云提供商都通过其他方式扩展其基本IaaS产品的功能,例如用于数据分析、事件处理和关系数据库的一系列Web服务。

9700

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励