实现分布式mysql神器之Cobar

Cobar简介

Cobar来源于强大的阿里团队。随着业务量的迅速增长,属于量也跟随迅猛增长。单点的Oracle+小型机出现了瓶颈,不能满足业务需求。摆在面前的有三种选择:

  • 级小型机的硬件

  • 购买多台小型机以分散各个业

  • 以廉价PC服务器+开源数据库替代之

很显然第三种选择的优势远远大于前两种。于是乎,强大的阿里团队选择了第三种方案,因而解决了下面几个问题:

  • 数据和访问从集中式改变为分布式

  • 提供数据节点的failover

  • 解决连接数过大的问题

  • 对业务代码侵入性少

据说截至2012年6月开源Cobar,作为数据库中间件Cobar已在阿里巴巴B2B公司稳定运行了3年以上。


获取Cobar

此处不得不唠叨几句,作为阿里的开源产品,在开源之初应该是可以从官方网站获取到的,也不知为什么现如今所谓的官方网址http://code.alibabatech.com/wiki/display/cobar/release/已无法访问。但是我们可以从github上download。

在获取到的文件夹下有如图所示几个子目录

实现分布式mysql神器之Cobar_第1张图片

很明了的可以看出,doc里存放了一些关于Cobar的文档,其余三个便是source code,driver是类似于mysql-jdbc的一个连接驱动源码。manager是一个web类型的Cobar客户端监视源码。最主要的是最后一个Server,所有的核心部分便在这个里面。


安装

由于Cobar的源码是基于maven构建的,有必要安装maven。至于maven的安装此处不做以详解(下载maven压缩包解压并配置M2_HOME).

在Cobar-Master/erver目录下执行mvn package命令。在执行完后会在Server源码文件夹的target的目录下发现两个分别命名为"cobar-server-1.2.7.tar.gz"和“cobar-server-1.2.7.zip”的两个压缩包。很明显的在Windows上使用后者,在Linux上使用前者。

解压压缩包。运行startup 脚本。此处不得不注意下startup.bat文件中指定的cobar 版本号问题,因为源码编辑得到的版本是1.2.7,而startup.bat默认指定的是1.3.0。若不修改,当运行的过程中将会提示错误找不到主类(main class).当然对于此类中间件是建议在Linux上run的,对于上述问题便可不加关心。此处还是着重介绍下在Linux环境下的安装:

  • jdk是必须的,无论是系统默认安装的jdk还是个人手动安装的,都需要配置环境变量。以下仅作为参考:

vim /etc/profile

//添加下列内容
export JAVA_HOME=/usr/lib/jvm/jre-1.7.0-openjdk.x86_64

  • mysql数据库当然是必须的,关于mysql的安装以及多个实例的实现请参考CentOS 安装多个mysql实例。

  • 将Cobar的压缩包cobar-server-1.2.7.tar.gz通过winscp或者pscp工具复制到centos上的某个目录下,例如/home下。

tar -xzvf cobar-server-1.2.7.tar.gz
//解压出来的内容如下
cobar-server-1.2.7/lib/log4j-1.2.17.jar
cobar-server-1.2.7/lib/cobar-server-1.2.7.jar
cobar-server-1.2.7/bin/
cobar-server-1.2.7/bin/restart.sh
cobar-server-1.2.7/bin/shutdown.sh
cobar-server-1.2.7/bin/startup.bat
cobar-server-1.2.7/bin/startup.sh
cobar-server-1.2.7/conf/
cobar-server-1.2.7/conf/log4j.xml
cobar-server-1.2.7/conf/rule.xml
cobar-server-1.2.7/conf/schema.xml
cobar-server-1.2.7/conf/server.xml

配置

分析一下解压的到的Cobar目录结构与其他程序也没什么区别:bin,conf,lib当然在未启动之前log目录是看不到的。

bin目录下的就是可运行的shell脚本,根据命名规则便可知道各个脚本的作用:

  • startup.sh启动Cobar服务的脚本

  • shutdown.sh停止Cobar服务的脚本

  • restart.sh重启Cobar服务的脚本

lib目录下测存放的是Cobar运行时所依赖的jar文件:

  • cobar-server-1.2.7.jar就是通过源码所生成的,启动有一个main方法使的该jar文件具有executable特性

  • log4j-1.2.17.jar是Cobar所依赖的日志管理工具。

conf目录下是存放了Cobar运行所读取的几个xml配置文件:

  • log4j.xml自然是配置日志信息,在Java项目下大家基本都了解,此处不做过多解释。

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

  <appender name="STDOUT" class="org.apache.log4j.DailyRollingFileAppender">
    <param name="file" value="${cobar.home}/logs/stdout.log" />
    <param name="append" value="true" />
    <param name="encoding" value="UTF-8" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %-5p %m%n" />
    </layout>
  </appender>
  <appender name="ALARM" class="org.apache.log4j.DailyRollingFileAppender">
    <param name="file" value="${cobar.home}/logs/alarm.log" />
    <param name="append" value="true" />
    <param name="encoding" value="UTF-8" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %-5p %m%n" />
    </layout>
  </appender>
  <appender name="HEARTBEAT" class="org.apache.log4j.DailyRollingFileAppender">
    <param name="file" value="${cobar.home}/logs/heartbeat.log" />
    <param name="append" value="true" />
    <param name="encoding" value="UTF-8" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %-5p %m%n" />
    </layout>
  </appender>

  <logger name="com.alibaba.cobar.CobarServer">
    <level value="info" />
  </logger>
  <logger name="com.alibaba.cobar.net.handler.FrontendAuthenticator">
    <level value="info" />
  </logger>
  <logger name="com.alibaba.cobar.mysql.MySQLDataNode">
    <level value="info" />
  </logger>
  <logger name="alarm">
    <level value="error" />
    <appender-ref ref="ALARM" />
  </logger>
  <logger name="heartbeat" additivity="false">
    <level value="warn" />
    <appender-ref ref="HEARTBEAT" />
  </logger>

  <root>
    <level value="warn" />
    <appender-ref ref="STDOUT" />
  </root>

</log4j:configuration>

  • schema.xml关于数据库配置的文件。

此处需要提示的是由于windows与linux在文本编码方面的存在的一些差异,不建议在xml配置文件中用中文注释,否则会在启动Cobar过程中因读取xml而发生异常如下。

Caused by: com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 3 of 3-byte UTF-8 sequence.
	at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(UTF8Reader.java:687)
	at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(UTF8Reader.java:435)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1753)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.scanData(XMLEntityScanner.java:1252)
	at com.sun.org.apache.xerces.internal.impl.XMLScanner.scanComment(XMLScanner.java:778)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanComment(XMLDocumentFragmentScannerImpl.java:1046)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2980)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
	at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
	at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:347)
	at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:121)
	at com.alibaba.cobar.config.util.ConfigUtil.getDocument(ConfigUtil.java:107)
	at com.alibaba.cobar.config.loader.xml.XMLSchemaLoader.load(XMLSchemaLoader.java:114)
	... 7 more

在schema.xml里主要配置了数据源以及数据节点,对于schema的配置里可以为table指定路由规则,至于路由规则的来源下面会有说明。如果所有数据源的用户名与密码相同可以配置在同一datasource节点下。系统会将其组装为一个数组,当为数据节点指定数据源时只需用数组下标以及数据源名称表示即可例如dsTest[1].同时可以为数据节点指定心跳检测运行情况,当主数据源出现异常的时候便可切换到备数据源,遗憾的是当主数据源恢复正常的时候不能自动切换会主数据源,除非备数据源也发生异常。

<cobar:schema xmlns:cobar="http://cobar.alibaba.com/">

  <!-- Define schema, as following name represents schema name or db name. Here, we defined one schema named 'dbtest'. For table tb2, we assigned route rule(rule1) for it. Means that data 
  will be insert dnTest2 and dnTest3 while executing insert operation for tb2. -->
  <schema name="dbtest" dataNode="dnTest1">
    <table name="tb2" dataNode="dnTest2,dnTest3" rule="rule1" />
  </schema>

  <!-- Defined data node. For dataSourceRef column, if we only assign one datasource, it will 
  be treated as master. If we want assign one or more slaves, just add one or more lines.-->
  <dataNode name="dnTest1">
    <property name="dataSource">
      <dataSourceRef>dsTest[0]</dataSourceRef>
    </property>
    <property name="heartbeatSQL">select user()</property
  </dataNode>
  <dataNode name="dnTest2">
    <property name="dataSource">
      <dataSourceRef>dsTest[1]</dataSourceRef>
    </property>
  </dataNode>
  <dataNode name="dnTest3">
    <property name="dataSource">
      <dataSourceRef>dsTest[2]</dataSourceRef>
    </property>
  </dataNode>

  <!-- Define datasource-->
  <dataSource name="dsTest" type="mysql">
    <property name="location">
      <location> 192.168.241.128:3306/dbtest1</location>
      <location> 192.168.241.128:3306/dbtest2</location>
      <location> 192.168.241.128:3306/dbtest3</location>
    </property>
    <property name="user">root</property>
    <property name="password"></property>
    <property name="sqlMode">STRICT_TRANS_TABLES</property>
  </dataSource>

</cobar:schema>

  • rule.xml文件则是配置路由规则,即指定表的分区规则。

阿里的源码里只提供了根据long型数据分区,根据String类型数据分区,根据FileMap分区。而我们通常很多情况下需要用时间分区,怎么办的。还好有位大神级人物在2014年6月份开源了一个扩展,我们可以从github上download下来使用。至于用法可以将其复制到Cobar目录下打包,也可以单独打包将其直接添加到lib目录。对于tableRule在配置的时候,由于Cobar只支持1维和2维路由。所以对于同一tablerule最多只能为两个字段配置路由规则。当然一般情况下一个字段的路由已经够用了。

<!DOCTYPE cobar:rule SYSTEM "rule.dtd">
<cobar:rule xmlns:cobar="http://cobar.alibaba.com/">

  <tableRule name="rule1">
    <rule>
      <columns>id</columns>
      <algorithm><![CDATA[ func1(${id}) ]]></algorithm>
    </rule>
  </tableRule>

  <function name="func1" class="com.alibaba.cobar.route.function.PartitionByLong">
    <property name="partitionCount">2</property>
    <property name="partitionLength">512</property>
  </function>

</cobar:rule>

  • server.xml关于Cobar运行的一些参数设定。

若不做特定设置,Cobar将运行于8066端口以及9066端口,所以你懂得,这两个端口也应该开放的。同时需要为Cobar服务设置用户名及密码以便调用Cobar服务时使用。

<cobar:server xmlns:cobar="http://cobar.alibaba.com/">
  
  <!--
  <system>
    <property name="serverPort">8066</property>
    <property name="managerPort">9066</property>
    <property name="initExecutor">16</property>
    <property name="timerExecutor">4</property>
    <property name="managerExecutor">4</property>
    <property name="processors">4</property>
    <property name="processorHandler">8</property>
    <property name="processorExecutor">8</property>
    <property name="clusterHeartbeatUser">_HEARTBEAT_USER_</property>
    <property name="clusterHeartbeatPass">_HEARTBEAT_PASS_</property>
  </system>
  -->

  <user name="test">
    <property name="password">test</property>
    <property name="schemas">dbtest</property>
  </user>
  <!--
  <user name="root">
    <property name="password"></property>
  </user>
  -->

  <cluster>
    <node name="cobar1">
      <property name="host">192.168.241.128</property>
      <property name="weight">1</property>
    </node>
  </cluster>
   
  <!--
  <quarantine>
    <host name="1.2.3.4">
      <property name="user">test</property>
    </host>
  </quarantine>
  -->

</cobar:server>

到此配置文件已解说完成,更加详细的说明可以参考文档Cobar - Alibaba Open Sesame.pdf

启动

在以上工作都完成后就可启动Cobar,即运行startup.sh脚本。

启动成功执行 ps -ef | grep cobar将会看到下图所示

实现分布式mysql神器之Cobar_第2张图片

并可通过mysql命令登录Cobar,指定主机为安装Cobar的Server,username和password则是Cobar server.xml里设置的用户名和密码,结果如下图所示:

实现分布式mysql神器之Cobar_第3张图片

Help

若有疑问可微信扫描下列二维码并关注留言

实现分布式mysql神器之Cobar_第4张图片

你可能感兴趣的:(数据库,mysql,分布式,cobar)