内容提要
数据库架构需兼顾可用性、读性能、一致性与扩展性。分片解决数据量问题,常用哈希路由;分组通过主从复制提升可用性。可用性依赖冗余,但会引发一致性问题;读性能依赖索引、从库和缓存。一致性可通过中间件或强制读主缓解。扩展性支持平滑扩容与迁移。
延伸解读
分片路由的权衡:为何哈希成为主流
文章指出分片路由有范围、哈希和统一路由服务三种方式。范围路由简单易扩展,但新号段活跃导致各库压力不均;哈希路由数据均衡、负载均匀,但扩容时迁移麻烦;统一路由服务灵活解耦,却增加一次查询开销。多数互联网公司选择哈希路由,说明在数据均衡与迁移成本之间,均衡性更被看重,而迁移问题可通过其他方案缓解。
写高可用的代价:资源利用率与读扩展的取舍
冗余写库通过双主互备实现写高可用,但会带来双写同步冲突,需用不同初始值步长或业务生成ID解决。阿里云RDS采用类似双主同步,但只有一个主提供服务,另一个shadow-master仅作备份,故障时虚IP漂移对业务透明。这种方式读写无延时、无一致性问题,但无法通过加从库扩展读性能,且资源利用率仅50%,成本较高。
读性能扩展的副作用:同步延迟与一致性窗口
增加从库是扩展读性能的常见方法,但文章提醒,从库越多,同步越慢,数据不一致窗口越大。增加缓存同样会引入db与缓存间的不一致。因此,读性能的提升往往以一致性为代价。业务需根据场景选择:允许cache miss的场景可设置缓存超时以自修复,而对一致性要求高的读操作,可通过中间件路由到主库或强制读主来缓解。
Q&A
数据库分片后,数据路由有哪些常见方法?各有什么优缺点?
常见方法有三种:1. 范围路由:简单易扩展,但各库压力不均,新号段更活跃;2. 哈希路由:简单、数据均衡、负载均匀,但迁移麻烦,如2库扩3库需数据迁移;3. 统一路由服务:灵活性强,业务与路由算法解耦,但每次访问数据库前多一次查询。大部分互联网公司采用哈希路由。
如何保证数据库的写高可用?阿里云RDS是怎么做的?
通过冗余写库,采用双主互备。阿里云RDS采用类似双主同步的方式,但只有一个主提供读写服务,另一个是shadow-master,只保证高可用,平时不提供服务。master挂了,shadow-master顶上,虚IP漂移,对业务层透明,无需人工介入。好处是读写无延时、无一致性问题,读写高可用;不足是不能通过加从库扩展读性能,资源利用率50%。
提高数据库读性能有哪些方式?各有什么缺点?
三种方式:1. 增加索引:不同库可建不同索引,如写库不建索引,线上读库建线上访问索引,线下读库建线下访问索引;2. 增加从库:从库越多同步越慢,数据不一致窗口越大;3. 增加缓存:常见架构为上游业务应用,下游主库、从库、缓存。若服务化,中间加服务层屏蔽底层复杂性。但数据复制多份会引发一致性问题。
主从数据库的一致性如何保证?
通常有两种解决方案:1. 中间件:如果某个key有写操作,在不一致时间窗口内,中间件将该key的读操作也路由到主库;2. 强制读主:双主高可用架构下,主从一致性问题能大大缓解。另外,db与缓存间的不一致建议所有允许cache miss的业务场景,缓存KEY设置超时时间,以便有机会自修复。
数据库软件架构设计主要考虑哪些方面?
至少要考虑四点:1. 如何保证数据可用性;2. 如何提高数据库读性能(大部分应用读多写少,读会先成为瓶颈);3. 如何保证一致性;4. 如何提高扩展性。
双主互备写库时,如何解决自增ID同步冲突?
有两种常见解决方案:1. 两个写库使用不同的初始值,相同的步长来增加id,例如1写库的id为0,2,4,6…,2写库的id为1,3,5,7…;2. 不使用数据的id,业务层自己生成唯一的id,保证数据不冲突。