最近接了个活,后端得做高负载的处理,我想要分库处理。论坛里有朋友后端数据库是多个的么?你们是如何做夸库的事务处理的呢?貌似 rails 是不支持两阶段提交的。请问大家有什么好方案呢?
首先,你确定你需要分库?所谓的高负载就是要分库么?你数据量有哪么大么?有多大,单表记录数量上亿了么?这活你收的钱上几十万、上百万了吗?
不要想当然!
或许有天是有可能有大么大数据量,这个时候你需要 找个 DBA! 介于你是一个外包,不可能走前面条路,你可以选择用 Aliyun RDS 之类的服务,让云服务提供商帮你管理数据库。
此外你还需要从应用层考虑如何实现分表,基于什么条件拆分,这个在一开始就要考虑好。
我和 @qhwa @psvr @sapronlee @tuliang @wxianfeng 在阿里云搞过一次这样的场景,接手了一个项目,主业务的表已经有超过 10 亿的数据量了,我们从一开始设计项目的时候就得考虑分库分表的问题。
但你光靠 Rails 或 Ruby 的技术栈是没法的(或者说很难搞下来的),同时这也是作为 Web 开发或者 Web 架构师很难。我们只是负责从应用层,让业务、数据结构的设计能符合基于某些字段条件进行分表(例如 user_id),基于 user_id 取余 1024 来分表,背后的分表规则处理是由一个介于应用服务和数据库之间的 Proxy 服务来实现,里面会基于一些预定的分库分表规则将 SQL 语句指向到不同的数据库或表(开源社区应该有类似的方案)。
关于你问的事务问题,其实就是要从设计分表字段的地方考虑好,避免跨表跨库的查询出现(当然是尽可能的)。
当然具体执行起来时非常繁琐复杂的,而且还要破坏 ActiveRecord 的一些基础结构,我们甚至都为了实现这样的支持,在应用里面给 ActiveRecord 打了一些 Monkey Patch。
此外,我认为,我们绝大多数人(指 Rails Web 开发)顶多能发展为应用架构师,而不是系统架构师或者 DBA,这些场景是专业领域,应该在合适的时机找专业的人配合。不可能全部吃透,人的经历(精力)有限,光搞好应用架构都需要非常多知识。这年头 Aliyun 这样的一整套云服务目的就是为应用架构师服务的,那些背后复杂的服务器运维、数据库管理等工作让专业的人来独立负责,以便于各类大中小型企业(项目)能把精力关注在业务和应用上。
@huacnlee 这样分 1024 张表,之后其他跟用户表相关的表你们是如何处理的?是不是为了查询性能,增加了很多陇余的表?比如将跟用户相关的订单表按照用户的 id 分布规律,划分了分表..但是订单表又可能要按照 product_id 来查询,是不是又要根据 product_id 的分表规律,来再划分一次订单的分表?
应用层只有一个 Model,以照片应用为例(实际上我们就是照片应用)
Photo 表,背后是 photos_1 - photos_1024,但 Model 只有一个,查询在 Rails 输出的时候还是:
select * from photos where user_id = ?
但到了 MySQL Proxy 层(阿里内部的非开源系统),将会分析这条 SQL,找到 user_id
关键字,并基于之前的分库分表设计,将 photos
换成 photos_(n)
,最后再往后面的 MySQL 发送请求。
但这样做有局限性,无法跨表查询或跨表查询会相对较慢,例如这样的语句场景会有问题(同时查询 user_id in (1, 2, 3)),1, 2, 3 的用户的 Photo 可能分布在不同的 photos_(n) 表里面,Proxy 需要分别查询最后再组合在一块儿,所以很多的实现都需要避开这样的问题。
所以,根据实际业务场景,选择合适的分表字段是很重要的!例如订单的场景,绝大多数场景一定都是自己看自己的订单,所以基于 user_id
拆分表是可行的。同理,Timeline,Notification 也是可以的。
以上都是理论,实际执行的时候比较复杂。并且,核心点还是你需要中间层的分库框架。
@huacnlee 我想我是不需要分库分表了。谢谢你的耐心解答 0rz.我还有个问题一直不懂。是不是把一百万用户的信息放到 redis 里面,读取速度会比从 mysql 读取要快?在 mysql 中根据 id 查询,和从 redis 中按照 user_id 读取,哪个更快呢? 根据我以前碰到的问题,貌似 mysql 里两张内存中的临时表,对某个数字字段做关联查询,查询速度比在硬盘上的两张表,对数字字段加索引后,进行关联。查询的要慢.是不是在 mysql 中的内存中的表,进行关联查询,是要做全表扫描的?
MySQL 主键、基于索引的查询,哪怕几百万的数据,也是非常快的。
不要听传言说 Redis 快、MongoDB 快就去用那些东西,前提还是你懂他们不?你知道他们适用的场景不?
飞机比汽车快,但你会开么?以及飞机能在城里开么?
前面都说了,要看场景选择合适的方案。至于怎么知道什么适合你,你需要去了解这些东西(MySQL、Redis ...)它们适用于什么场景,优缺点是什么。
你的第二句我没看懂...
#11 楼 @happyming9527 我们用的是 PostgreSQL,延时具体没有测过,这个还是得看应用场景。重要的都放倒事务里面,基本上不会出啥问题。
#11 楼 @happyming9527 我们用的是 PostgreSQL,延时具体没有测过,这个还是得看应用场景。重要的都放倒事务里面,基本上不会出啥问题。