DBproxy

通过引入数据访问中间件,可以实现对应用透明的分库分表。一个比较好的实践是:逻辑拆分先一步到位,物理拆分慢慢进行。以账户表为例,将用户ID的末两位作为分片维度,可以在逻辑上将数据分成100份,一次性拆到100个分表中。这100个分表可以先位于同一个物理库中,随着系统的发展,逐步拆成2个、5个、10个,乃至100个物理库。数据访问中间件会屏蔽表与库的映射关系,应用层不必感知。



虽然数据库是按用户维度水平拆分的,但是应用层流量是完全随机的。以图中的简化业务链路为例,任意一个核心应用节点C可能访问任意一个数据库节点D,都需要占用数据库连接。连接是数据库非常宝贵的资源,是有上限的。当时的支付宝,面临的问题是不能再对应用集群扩容,因为每增加一台机器,就需要在每个数据分库上新增若干连接,而此时几个核心数据库的连接数已经到达上限。应用不能扩容,意味着支付宝系统的容量定格了,不能再有任何业务量增长。

 

 
单元化架构基于这样一种设想:如果应用层也能按照数据层相同的拆片维度,把整个请求链路收敛在一组服务器中,从应用层到数据层就可以组成一个封闭的单元。数据库只需要承载本单元的应用节点的请求,大大节省了连接数。

单元化有几个重要的设计原则:

  • 核心业务必须是可分片的
  • 必须保证核心业务的分片是均衡的,比如支付宝用用户ID作分片维度
  • 核心业务要尽量自包含,调用要尽量封闭
  • 整个系统都要面向逻辑分区设计,而不是物理部署

数据库的读写操作需要有数据库连接池来保障系统稳定性,因此数据库读写接口仍需要c server来承担(也可以是go等其它有连接池功能的server)。

原因:业务层是不能直连数据库的,连接的是dbproxy,由dbproxy去连接数据库。然而dbproxy层并不具备完善的连接池功能,当请求数突增,比如秒杀场景时,短时产生的大量dbproxy连接请求,超过dbproxy最大连接数配置后,请求会被直接拒绝,造成业务失败。因此我们需要一个连接池功能,能暂存突增的连接请求排队消费。c server基于yapserver框架的多线程模型,在c server启动时就与dbproxy建好了长连接,因此c server到dbproxy层不需要担心连接数问题。当PHP层连接数突增时,基于yapserver框架的c server能够先把请求接下来并排队,而不是直接拒绝请求,这样业务系统更加稳定。

 

posted @ 2022-02-14 16:54  dsfsadfdgd  阅读(502)  评论(0)    收藏  举报