数据库架构设计要点
如何解决数据量大的问题
垂直拆分
垂直拆分的原则
- 将长度较短,访问频率较高的属性尽量放在一个表里,这个表暂且称为主表
- 将字段较长,访问频率较低的属性尽量放在一个表里,这个表暂且称为扩展表
- 经常一起访问的属性,也可以放在一个表里
访问主表和扩展表时,最好分别访问以保证性能,最好不要通过join访问,一方面会影响性能,另一方面采用join主表和扩展表都在一个实例上不利于分库,和提高性能的初衷相矛盾
为什么将长度较短,访问频率高的属性放在一张表里
数据库实例都有自己的buffer,长度短意味着可以缓存更多的数据,以提高内存命中率提高性能
水平拆分
水平拆分后,势必引入新的问题如何对数据进行路由,大体有2种思路
- 算:一致性hash、取余 、range
- 查:新增路由服务,每次访问数据库之前多一次查询操作
当水平拆分后,对于非主键的查询则变得非常的不方便,如何解决
- 查:
- 建立非主键字段到主键的索引表
- 将非主键到主键的映射关系放入cache缓存
- 算:
- 是否可以通过某种算法将非索引主键和主键建立关系,通过以算代查
从运营层面来看,还有一种需求是就是运营需要的各种奇葩查询,如果复杂查询查询线上数据库,会导致线上数据库性能下降,所以常用的做法是前台和后台分离,数据库完全是两套,出于运营需要可以建立各种索引,甚至可以采用“外置索引”(例如ES搜索系统)或者“大数据处理”(例如HIVE)来满足后台变态的查询需求
高可用
常用的高可用方案就是冗余,数据库也不例外
读高可用
优点:读写分离,提升性能
缺点:数据一致性的问题
读写高可用方案一
优点:读写分离,提升性能
缺点:
- 写库也采用了冗余,但是带来的问题,数据可能会有冲突,如何解决
- 2个库id采用不同的初始值,相同步长
- 应用层保证id不冲突
- 数据一致性问题
读写高可用方案二
读写都在master上,slave存提供备份,不提供服务,一旦master挂掉,vip漂移主备切换
优点:
- 数据保持一致
- 读写高可用
缺点
- 无法通过扩展数据库提升性能,如何提升可以通过redis
- slave完全冷备
性能
增加索引
增加从库,读写分离
增加缓存,之前在58时,常用的方法如下:
一致性
主从数据库的一致性
- 引入数据库中间件,在主从数据不一致的窗口期内,中间件强制将key路由到主库上
- 在58的场景下,由于主库承担读和写,不存在主从不一致的场景
db和缓存的一致性
读操作:读cache,如果命中直接返回,未命中读db,在更新cache
写操作:cache双淘汰+设置过期时间(淘汰cache,写数据库,在一个经验值值(1s)再次发起淘汰cache,同时为每个cache中item设置过期时间,以此来保障最终一致性)
db和缓存在什么场景下会出现不一致的情况?
当只有1个主db的情况:由于数据库层面的读写是并发执行的,当执行写、读操作时,如果读先于写先执行了,则会读到旧数据到cache中,导致db和cache数据不一致。
当一主多从的情况:当主从数据还未同步完成之前,有读请求到从db,则会读到旧数据到cache中,导致db和cache数据不一致
解决不一致的方案
串行化,此种方案仅适用于没有从库的场景,总体的思想就是通过串行化保证删cache-写db-读db能顺序执行
如上图所示是一个典型的web框架,暂时先不讨论session的一致性,我们暂时先讨论到web server之后,保证读写顺序一致性,webserver之后有2处是并行执行的,webserver到中间件(不同的请求会从连接池选择不同的连接),中间件到db(不同的请求会从连接池选择不同的db连接),先写后读请求到了webserver之后,要根据操作数据的标识(比如同一个表的同一个id)作为key(取模或一致性hash)保证请求到同一个数据库中间件的同一个连接,中间件根据同样的key从db连接池中获取一个连接,要保证同一个key的1-删cache、2-写db、3-读db的顺序执行,通过串行化来保证db和cache的数据一致性。
cache双淘汰
- 先淘汰缓存
- 再写数据库
- 休眠1秒,异步删除cache,方案有如下2种
异步删cache
方案一,通过消息总线异步删除cache
方案二,通过订阅binlog,异步删除cache
可扩展性
在58时,感觉58的数据库架构是一套对扩展性非常友好的方案,可以做到秒级扩容,数据不需要迁移
- 每次扩容都是double
- 从库变主库,由于扩容前从库数据是全量数据,所以不需要数据迁移
- 解除旧的双主关系,增加新的双主
- 删除冗余数据
扩展表属性
对于一个不能保证事务性的操作,一定涉及哪个任务先做,哪个任务后做的问题,往往出问题的点在于第一个成功,第二个失败后果会如何,所以可以分别比较下哪种顺序后果对业务影响最小,就选择哪种