首页 > 编程知识 正文

数据库是结构化的数据集合,数据库的数据结构

时间:2023-05-03 21:39:27 阅读:166176 作者:112

一.基本概念

二.数据库体系结构的设计思路

)1)可用性

(2)读取性能

(3)一致性

)4)可扩展性

一.基本概念

概念1“单一库”

概念2“瓷砖”

平铺解决的问题是“数据量过多”的问题,也就是通常所说的“水平分割”。

随着分片的引入,“数据路由”的概念确定了哪些数据将访问哪些库。

路由规则通常有三种方法。

(1)范围:范围

优点:简单,易于扩展

缺点:各围堰的压力不均匀(新号段更活跃) ) )。

)2)散列)散列

优点:简单,数据均衡,负载均匀

缺点:迁移麻烦(2库扩展3库数据迁移) )。

(3)路由服务:配置服务器

优点:灵活性强,业务与路由算法解耦

缺点:每次访问数据库时增加一次查询

大多数互联网企业采用的方案2 :散列库、散列路由

概念3“分组”

分组解决了“可用性”问题。 分组通常通过主从方式实现。

互联网企业数据库的实际软件体系结构进行了分片和分组,如下图所示

二.数据库体系结构的设计思路

数据库软件架构师平时设计什么? 请至少考虑以下四点。

)1)如何确保数据可用性

)2)如何提高数据库的读取性能)大多数APP读多写少,读取先成为瓶颈)。

)3)如何保证一致性

)4)如何提高可扩展性

2.1如何确保数据可用性?

解决可用性问题的思路是=冗馀

如何确保网站的可用性? 复制站点、冗馀站点

如何保证服务的可用性? 复制服务、冗馀服务

如何确保数据的可用性? 数据复制,冗馀数据

数据冗馀会导致副作用=一致性问题(一致性问题暂且不谈,可用性问题暂且不谈) )。

如何确保数据库的“读取”可用性?

冗馀库

阅读冗长的库带来的副作用? 读写有延迟,可能不一致

上图为多家互联网公司mysql的体系结构,写入仍然是单点,无法保证写入的可用性。

如何确保数据库的“写入”可用性?

冗馀写入库

采用双主互备方式,可以冗余地编写数据库.

副作用是? 解决两个写同步、可能的数据冲突(例如,“自增长id”同步冲突)和同步冲突的常见解决方案有以下两种:

)1) 2个写入数据库通过不同的初始值、同一步骤增加id。 1写入库的id为0、2、4、6…; 2库的id为1、3、5、7…

)2)不使用数据的id,业务层独自生成唯一的id,避免数据冲突

58同城没有使用上述两种框架读写的“高可用性”,58同城采用“两主为主从”的方式。

虽然还是双主机,但只有一个主机在提供服务。 另一个主机是“shadow-master”,只是为了确保高可用性,平时不提供服务。

主控锁定,shadow-master居首位(vip漂移,对业务层透明,无需人工干预) ) ) ) ) ) )。

这个方法的优点:

1 )读写及时

2 )读写可用性高

不足:

1 )无法通过添加从库扩展读取性能

2 )资源利用率50%,冗主不服务

那么,如何提高读取性能呢? 进入第二个话题,如何提供读取性能?

2.2如何扩展引脚性能?

提高读取性能的方法大致有三种,第一种是建立索引。 这种方式没有展开,应该提到的是,不同的数据库可以制作不同的索引。

不在库中创建索引;

联机库创建联机访问索引,如uid

联机库创建联机访问索引,例如time。

第二种扩展读取性能的方法是增加从库。 这个方法大家用得很多,但有两个缺点。

)库越多,同步越慢

)2)同步越晚,数据不一致窗口越大(不一致是在后面叙述,还是先说提高读性能) )。

58同城没有通过该方法提高数据库的读取性能,而是采用增加缓存。 典型的缓存体系结构如下。

上游是业务APP,下游是主库、库(读写分离)、缓存。

58同城的游戏是服务数据库缓存集

业务层不直接面向db和cache,服务层屏蔽了底层db、cache的复杂性。 为什么要部署服务层,今天不展开,58采用“服务数据库缓存集”的方式提供数据访问,通过缓存提高了读取性能。

无论是用主从方式扩展读性能,还是用缓存方式扩展读性能,数据都必须复制多份(主从、db cache ),会引起一致性问题。

2.3如何保证一致性?

主从数据库的一致性,通常有两种解决方案:

(1)中间件


如果某一个key有写操作,在不一致时间窗口内,中间件会将这个key的读操作也路由到主库上。

这个方案的缺点是,数据库中间件的门槛较高(百度,腾讯,阿里,360等一些公司有,当然58也有)

(2)强制读主


58的“双主当主从用”的架构,不存在主从不一致的问题。

 

第二类不一致,是db与缓存间的不一致


常见的缓存架构如上,此时写操作的顺序是:

(1)淘汰cache

(2)写数据库

读操作的顺序是:

(1)读cache,如果cache hit则返回

(2)如果cache miss,则读从库

(3)读从库后,将数据放回cache

 

在一些异常时序情况下,有可能从【从库读到旧数据(同步还没有完成),旧数据入cache后】,数据会长期不一致。

 

解决办法是“缓存双淘汰”,写操作时序升级为:

(1)淘汰cache

(2)写数据库

(3)在经验“主从同步延时窗口时间”后,再次发起一个异步淘汰cache的请求

 

这样,即使有脏数据如cache,一个小的时间窗口之后,脏数据还是会被淘汰。带来的代价是,多引入一次读miss(成本可以忽略)。

 

除此之外,58同城的最佳实践之一是:建议为所有cache中的item设置一个超时时间。

 

说完一致性,最后一个话题是扩展性。

2.4如何提高数据库的扩展性?

原来用hash的方式路由,分为2个库,数据量还是太大,要分为3个库,势必需要进行数据迁移,58同城有一个很帅气的“数据库秒级扩容”方案。

如何秒级扩容?

首先,我们不做2库变3库的扩容,我们做2库变4库(库加倍)的扩容(未来4->8->16)

服务+数据库是一套(省去了缓存)

数据库采用“双主”的模式。

 

扩容步骤:

第一步,将一个主库提升

第二步,修改配置,2库变4库(原来MOD2,现在配置修改后MOD4)

扩容完成

原MOD2为偶的部分,现在会MOD4余0或者2

原MOD2为奇的部分,现在会MOD4余1或者3

数据不需要迁移,同时,双主互相同步,一遍是余0,一边余2,两边数据同步也不会冲突,秒级完成扩容!

 

最后,要做一些收尾工作:

(1)将旧的双主同步解除

(2)增加新的双主(双主是保证可用性的,shadow-master平时不提供服务)

(3)删除多余的数据(余0的主,可以将余2的数据删除掉)


这样,秒级别内,我们就完成了2库变4库的扩展。

OK,今天主要分享了58同城,数据库软件架构上:

(1)如何保证数据可用性

(2)如何提高数据库读性能

(3)如何保证数据一致性

(4)如何进行秒级扩容

希望大家有收获,谢谢大家!

原文出自:数据库软件架构设计些什么

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。