解决方案
由于水平拆分牵涉的逻辑比较复杂,当前也有了不少比较成熟的解决方案。这些方案分为两大类:客户端架构和代理架构。
客户端架构
通过修改数据访问层,如JDBC、Data Source、MyBatis,通过配置来管理多个数据源,直连数据库,并在模块内完成数据的分片整合,一般以Jar包的方式呈现
这是一个客户端架构的例子:
可以看到分片的实现是和应用服务器在一起的,通过修改Spring JDBC层来实现
客户端架构的优点是:
-
应用直连数据库,降低外围系统依赖所带来的宕机风险
-
集成成本低,无需额外运维的组件
缺点是:
-
限于只能在数据库访问层上做文章,扩展性一般,对于比较复杂的系统可能会力不从心
-
将分片逻辑的压力放在应用服务器上,造成额外风险
代理架构
通过独立的中间件来统一管理所有数据源和数据分片整合,后端数据库集群对前端应用程序透明,需要独立部署和运维代理组件
这是一个代理架构的例子:
代理组件为了分流和防止单点,一般以集群形式存在,同时可能需要Zookeeper之类的服务组件来管理
代理架构的优点是:
-
能够处理非常复杂的需求,不受数据库访问层原来实现的限制,扩展性强
-
对于应用服务器透明且没有增加任何额外负载
缺点是:
-
需部署和运维独立的代理中间件,成本高
-
应用需经过代理来连接数据库,网络上多了一跳,性能有损失且有额外风险
各方案比较
如此多的方案,如何进行选择?可以按以下思路来考虑:
-
确定是使用代理架构还是客户端架构。中小型规模或是比较简单的场景倾向于选择客户端架构,复杂场景或大规模系统倾向选择代理架构
-
具体功能是否满足,比如需要跨节点
ORDER BY
,那么支持该功能的优先考虑 -
不考虑一年内没有更新的产品,说明开发停滞,甚至无人维护和技术支持
-
最好按大公司->社区->小公司->个人这样的出品方顺序来选择
-
选择口碑较好的,比如github星数、使用者数量质量和使用者反馈
-
开源的优先,往往项目有特殊需求可能需要改动源代码
按照上述思路,推荐以下选择:
-
客户端架构:ShardingJDBC
-
代理架构:MyCat或者Atlas
兼容MySQL且可水平扩展的数据库
目前也有一些开源数据库兼容MySQL协议,如:
-
TiDB(https://github.com/pingcap/tidb)
-
Cubrid(http://www.cubrid.org)
但其工业品质和MySQL尚有差距,且需要较大的运维投入,如果想将原始的MySQL迁移到可水平扩展的新数据库中,可以考虑一些云数据库:
-
阿里云PetaData(https://cn.aliyun.com/product/petadata/?spm=5176.7960203.237031.38.cAzx5r)
-
阿里云OceanBase(https://cn.aliyun.com/product/oceanbase?spm=5176.7960203.237031.40.cAzx5r)
-
腾讯云DCDB(https://www.qcloud.com/product/dcdbfortdsql.html)
NOSQL
在MySQL上做Sharding是一种戴着镣铐的跳舞,事实上很多大表本身对MySQL这种RDBMS的需求并不大,并不要求ACID,可以考虑将这些表迁移到NoSQL,彻底解决水平扩展问题,例如:
-
日志类、监控类、统计类数据
-
非结构化或弱结构化数据
-
对事务要求不强,且无太多关联操作的数据
原文出处:https://segmentfault.com/a/1190000006158186
END