#基于PhalApi的DB集群拓展 V0.1batephp
##前言## 先在这里感谢phalapi框架创始人@dogstar,为咱们提供了这样一个优秀的开源框架.mysql
编写本次拓展出于的目的是解决大量数据写入分析的问题,也但愿本拓展能对你们有些帮助,可以解决你们遇到的一样的问题.git
注:V0.1bate版本,不少功能尚不完善,只提供技术交流使用,请不要用户生产环境算法
附上:sql
官网地址:http://www.phalapi.net/数据库
开源中国Git地址:http://git.oschina.net/dogstar/PhalApi/tree/releaseapi
##1.原由##数组
说到为何写这个拓展,原由是这样的,在和产品交流的时候他们但愿能够存一些东西做为数据分析用,我考虑过hadoop可是若是说使用hadoop须要投入的成本过高了,在想有没有什么好办法的时候,想到了分表分库解决数据量大的问题,那么能够有一个封装好的服务就和操做数据库同样操做能够达到良好的分表分库的效果吗,出于这个考虑就开始这个拓展的编写.缓存
##2.业务场景##服务器
大量select
当一个数据库须要对付大量的select请求的时候,咱们每每会想到使用读写分离来解决此类问题,一个写库多个读库,一台或多台服务器用一个读库,全部的写入操做使用主库操做,应为是大量的select操做,读的压力被分配到了不少个读库实例,能够很好的解决问题大量select的问题,再者就是进行添加缓存机制的优化,这样也是能很好的解决问题
大量的insert
对于大量insert上面所谓的读写分离彻底不够看了,全部的压力所有会集中在负责写入的主库,但并非应为并发请求的问题,问题是在于数据量大致使不论是干吗都会慢,当数据量到了上亿的级别简直不敢想像,若是是经过分表分库(若是是4库4表也就是16张表),数据分均衡的分配到(库数量-乘-表数量)这么多张表里面从而达到解决大量数据的问题(在分表分库前面有一个主表),固然他也有缺陷就是当进行条件查询的时候最坏的条件会遍历(库数量-乘-表数量)这么多张表才能得到想要的结果,因此不是很建议用到查询列表比较平凡的应用中,固然结合缓存和读写分离能够缓解压力
##3.使用拓展##
###3.1 下载/注册拓展###
你们能够到Git项目PhalApi Library下载拓展文件,把其中的DB_Cluster文件夹复制到/PhalApi/Library目录下,以下图:
把其中的Config中的cluster.php文件放到默认的Config配置文件中
而后在init.php中注册如下两句话
初始化配置文件 DI()->Cluster_DB = new Cluster_Lite(DI()->config->get('cluster'));
而后把框架自带的Demo文件替换成拓展自带的Demo文件以下就完成了第一步
###3.2 数据库集群初始化###
这里使用Mysql做为集群的数据库
你们能够看到拓展文件里面有一个Data/user_cluster.sql 文件,里面有一个 user_base的建表语句和另外user0,user1,user2,user3这四个表的建表语句
在文件里面有一些注意事项这里这里再次强调一下
--本次集群采起4库每一库4表 4*4共16表的mysql集群(基础库不算在里面) --基础库(id自增加,用表索引进行列表查询条件) --库名project --当本身创建集群mysql的时候要注意如下几点 --1.必定要注意ID要加上自动增加,这里进行的分表分库都是基于自增ID进行的,若是是自定义字符串ID须要进行算法修改,也可使用其余缓存生成自增ID --2.除了ID以外的字段(用于按条件查询列表ID)必定要加上索引或者是主键,否则数据量大的时候获取列表ID会很慢 --3.除了ID以外的字段必定要是更具业务需求进行查询比较频繁的,并且要保持尽可能的少1-2个,大于2个建议在分出一张表作对应 --库名分表为user_cluster0,user_cluster1,user_cluster2,user_cluster3(可自定) --下面四张表为每个库中都拥有的4张表(注意ID不能使用自动增加) --表名能够自定可是每一个库中的表名必定要统一 --user0,user1,user2,user3
我这里使用结构以下(你们能够自由的配置能够2库+2表,2库+4表等都行,只需在配置文件中配置就可)
数据库project -user_base表 数据库user_cluster0,user_cluster1,user_cluster2,user_cluster3 都有如下表 -user0,user1,user2,user3
###3.3 配置文件详解###
咱们需在在默认dbs.php 数据库配置中配置连接好project库
而后你们看向cluster.php集群配置文件按照注释配置好本身的数据库,若是没有多个mysql实例,能够一个实例创建4个库模拟4个mysql分布式集群.
这里指的着重讲一下的是如下配置问题
/** * 配置表 */ 'cluster' => array( //集群分布配置 'list' => array( 'demo' => array( //使用demo集群配置最大ID和最小ID,最大ID为0等于不上限 'id_min' => 0, 'id_max' => 0, ), ), //where查询条件放到衍生表中的字段 'where' => array( 'city' ), //ID名称 'id_name' => 'uId', ),
在list中能够配置多个集群数组KEY的名称对应配置文件上面demo集群而且能够设定ID范围,作这个设计主要是为了当我有一个2库*2表的集群,已经承载了1个亿的数据了,已经没法承担数据量了这个时候就要更换集群,在这里只须要吧demo的id_max配置成1亿,在配置一个demo1而后把id_min设定到1亿,当ID大于1亿了以后就会本身找到第二集群插入数据了(不用担忧多集群了以后查询以及其余操做这里已经作好了兼容)
还有where属性,这里的where用于配置在user_base表中除了ID以外的索引字段可以增长查询的性能,可是尽可能少应为这个会减小base表的性能,能够适当的取舍
###3.4 开始使用###
你们看向Demo的API文件中有四个接口select,delete,update,insert里面的参数都是随机生成的
在看向Cluster/User.php里面继承了Cluster_DB须要使用数据库集群就须要集成这个类而且实现如下两个方法
/** * 获取集群实例类 */ public function getCluster(){ return DI()->Cluster_DB; } /** * 获取主数据库表实例 */ public function getMainDB(){ return DI()->notorm->user_base; }
getCluster方法返回在init.php中注册DI()->Cluster_DB便可,由于一个集群对应一张表能够根据需求使用不通的集群实例
getMainDB方法是为了获取base表的实例只须要把表实例返回便可
当作好这几件事情你们就能够尝试请求接口看看结果了
##4. 实现思想讲解##
实现架构思惟
我在开始写这个拓展以前在想要让使用者如何去使用这个框架,怎么让使用者最方便,最后的到的答案是若是能够和正常使用Model层同样去使用的话是最好的,因此你们能够看到在Demo/Cluster/User.php中增删改查和正常使用基本没有区别.
分表分库算法
当咱们是2库2表的状况下,咱们用2乘2=4而后用咱们获取的ID好比55,用55%2乘2 就会获得一个小于4的数字,55获得的是3,用3/表数2=1.5取整是1表,而后用3%表数2=1,也就是存入1库1表(注意是从0开始算的)
##5. 基准测试##
###5.1 base表基准测试###
由于咱们的拓展是须要基于一个base表实现ID增加和where语句查询在分到集群库,因此base库须要应付的量比较大因此这里对base表进行了一次针对于不一样数据量进行的单ID查询和where查询基准测试
300w数据:
5700w数据:
1.3亿数据:
明显能够看出来随着数据量的增长查询速度有明显的下降,可是到了亿级的时候还能维持到where条件查询不上0.1秒的状况仍是比较理想的,最关键的是在亿级的时候插入仍是至关快的因此很是适合,大量数据的写入,若是是对查询有比较大的要求的童鞋能够考虑吧5000W做为一个分界点对基础base进行划分(后期将会把此功能集成到拓展内部)
###5.2 从小.中.大数据库就集群与单表实际状况并发对比###
应为工做量比较大还在进行测试中!
##6. 总结##
在此但愿本扩展能给你们带来解决实际问题的思路,初版是bate版本请不要使用在生产环境中,若是出现问题或者是有BUG能够直接联系我QQ591235675也可加入PhalApi交流群一同交流探讨
注:笔者能力有限有说的不对的地方但愿你们可以指出,也但愿多多交流!
官网QQ交流群:421032344 欢迎你们的加入!