Linux上面安装mysql 就不展开介绍了,这里就简单给出实验环境的表,就一张
CREATE TABLE `tb_message` (
`message_id` bigint(20) NOT NULL COMMENT '消息主键',
`content` varchar(1024) NOT NULL COMMENT '消息内容',
`from_user` varchar(64) NOT NULL COMMENT '消息发送者用户编号',
`to_user` varchar(64) NOT NULL COMMENT '消息接收者用户编号',
`send_time` timestamp NULL DEFAULT NULL COMMENT '发送时间',
`remark` varchar(128) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`message_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='测试消息数据表';
我在服务器A和服务器B都装好了mysql,并且创建了一样的database : db_test,同时向两个db中创建了tb_message表。为了方便直接使用root用户进行操作。到此数据库的操作先告一段落。
Mycat的历史可以到Mycat官方进行了解,这里直奔主题。Mycat是Java编写的,我们要从github把项目检下来,配置文件,然后运行。
这里我们需要把我们的物理数据库环境和mycat做个映射,简单来说就是告诉Mycat我的物理库在哪里,你要用哪个账号操作哪个表。
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="MESSAGEDB" checkSQLschema="true" sqlMaxLimit="1000">
<table name="tb_message" primaryKey="message_id" dataNode="dn1,dn2" rule="mod-long">table>
schema>
<dataNode name="dn1" dataHost="dhost1" database="db_test" />
<dataNode name="dn2" dataHost="dhost2" database="db_test" />
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()heartbeat>
<writeHost host="hostM1" url="172.19.155.20:3306" user="root" password="root">writeHost>
dataHost>
<dataHost name="dhost2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()heartbeat>
<writeHost host="hostM1" url="172.19.155.21:3306" user="root" password="root">writeHost>
dataHost>
mycat:schema>
mycat 也是一个服务,这里就是指明了服务的启动配置,可以把server当做是一个伪mysql,下面的user标签指明了连接此伪mysql的用户,8066为连接的端口,这点在持久层连接mycat的时候会进一步提现。
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="serverPort">8066property>
<property name="managerPort">9066property>
<property name="nonePasswordLogin">0property>
<property name="ignoreUnknownCommand">0property>
<property name="useHandshakeV10">1property>
<property name="removeGraveAccent">1property>
<property name="useSqlStat">0property>
<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+property>
<property name="subqueryRelationshipCheck">falseproperty>
<property name="sequenceHanlderClass">io.mycat.route.sequence.handler.HttpIncrSequenceHandlerproperty>
<property name="processorBufferPoolType">0property>
<property name="charset">utf8property>
<property name="sqlExecuteTimeout">300property>
<property name="sequenceHandlerType">1property>
<property name="useGlobleTableCheck">0property>
<property name="handleDistributedTransactions">0property>
<property name="useOffHeapForMerge">0property>
<property name="memoryPageSize">64kproperty>
<property name="spillsFileBufferSize">1kproperty>
<property name="useStreamOutput">0property>
<property name="systemReserveMemorySize">384mproperty>
<property name="useZKSwitch">falseproperty>
<property name="strictTxIsolation">falseproperty>
<property name="useZKSwitch">trueproperty>
<property name="parallExecute">0property>
system>
<user name="user1">
<property name="password">123456property>
<property name="schemas">MESSAGEDBproperty>
<property name="benchmark">5000property>
user>
mycat:server>
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="rule1">
<rule>
<columns>idcolumns>
<algorithm>func1algorithm>
rule>
tableRule>
<tableRule name="sharding-by-date">
<rule>
<columns>createTimecolumns>
<algorithm>partbydayalgorithm>
rule>
tableRule>
<tableRule name="rule2">
<rule>
<columns>user_idcolumns>
<algorithm>func1algorithm>
rule>
tableRule>
<tableRule name="sharding-by-intfile">
<rule>
<columns>sharding_idcolumns>
<algorithm>hash-intalgorithm>
rule>
tableRule>
<tableRule name="auto-sharding-long">
<rule>
<columns>idcolumns>
<algorithm>rang-longalgorithm>
rule>
tableRule>
<tableRule name="mod-long">
<rule>
<columns>message_idcolumns>
<algorithm>mod-longalgorithm>
rule>
tableRule>
<tableRule name="sharding-by-murmur">
<rule>
<columns>idcolumns>
<algorithm>murmuralgorithm>
rule>
tableRule>
<tableRule name="crc32slot">
<rule>
<columns>idcolumns>
<algorithm>crc32slotalgorithm>
rule>
tableRule>
<tableRule name="sharding-by-month">
<rule>
<columns>create_timecolumns>
<algorithm>partbymonthalgorithm>
rule>
tableRule>
<tableRule name="latest-month-calldate">
<rule>
<columns>calldatecolumns>
<algorithm>latestMonthalgorithm>
rule>
tableRule>
<tableRule name="auto-sharding-rang-mod">
<rule>
<columns>idcolumns>
<algorithm>rang-modalgorithm>
rule>
tableRule>
<tableRule name="jch">
<rule>
<columns>idcolumns>
<algorithm>jump-consistent-hashalgorithm>
rule>
tableRule>
<function name="murmur"
class="io.mycat.route.function.PartitionByMurmurHash">
<property name="seed">0property>
<property name="count">2property>
<property name="virtualBucketTimes">160property>
function>
<function name="crc32slot"
class="io.mycat.route.function.PartitionByCRC32PreSlot">
<property name="count">2property>
function>
<function name="hash-int"
class="io.mycat.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txtproperty>
function>
<function name="rang-long"
class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txtproperty>
function>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<property name="count">2property>
function>
<function name="func1" class="io.mycat.route.function.PartitionByLong">
<property name="partitionCount">8property>
<property name="partitionLength">128property>
function>
<function name="latestMonth"
class="io.mycat.route.function.LatestMonthPartion">
<property name="splitOneDay">24property>
function>
<function name="partbymonth"
class="io.mycat.route.function.PartitionByMonth">
<property name="dateFormat">yyyy-MM-ddproperty>
<property name="sBeginDate">2015-01-01property>
function>
<function name="partbyday"
class="io.mycat.route.function.PartitionByDate">
<property name="dateFormat">yyyy-MM-ddproperty>
<property name="sNaturalDay">0property>
<property name="sBeginDate">2014-01-01property>
<property name="sEndDate">2014-01-31property>
<property name="sPartionDay">10property>
function>
<function name="rang-mod" class="io.mycat.route.function.PartitionByRangeMod">
<property name="mapFile">partition-range-mod.txtproperty>
function>
<function name="jump-consistent-hash" class="io.mycat.route.function.PartitionByJumpConsistentHash">
<property name="totalBuckets">3property>
function>
mycat:rule>
其他模块就不再展开,搞了半天,终于按照设计的图把整个结构搞出来了,源码上传到github,像zookeeper和rabbitmq这种安装就不多累述,网上搜一下一大堆。
github测试源码
下面就贴出我压测的结果吧…
压测指令: ab -T ‘application/json;charset=UTF-8’ -n 50000 -c 500 http://localhost:8582/test
单个请求的大小是 11K,每秒平均并发写入是 3259.69/s , 也就说1秒钟3200+的写入,这个性能和我预期的还是有点差距的。。 虽然只有两台主机,但是我预期应该要到5000+的,下午再查查看哪里有问题, 总之现在就像吃了死老鼠一样的难受。
后续进行排查后,发现了几个问题,进行排查后重新进行测试。
问题:
经过调整后,整个并发的情况稳定在4500~5000之间,前后测试了30多次,结果基本都没有太大的偏差。
改进之后和预期的结果比较接近了,如果加上队列的缓冲,可能TPS还能再上去一些。不过实际环境业务比较复杂,一处小小的BUG都可能导致整个过程性能下降,所以写代码还是需要谨慎。 同时JVM对性能的影响也是很明显的,合理的调整JVM,使用垃圾收集器也是提升性能的关键手段。后续可能换一下G1垃圾收集器再测试下。