隨着.NetCore的發展,最近我們也順利的服務化、容器化了,生產環境全部跑在Linux了,下一步準備Devops。但隨着數據量的逐漸增多和所處行業的業務性質,個別服務對應的數據庫開始進行開始做分佈式數據庫了。前期也做過簡單的技術調研,比如efcore讀寫分離、新生命團隊的開源中間件XCode、以前有些服務基於CQRS開發的做一個小改動使之支持讀寫分離、MyCat中間件等,最終我們選用MyCat在一個服務上進行小規模使用。
MyCat是件,能做什麼,在這裏就不一一細說了,放一個官網鏈接,有興趣的朋友可以查看》http://www.mycat.io/
以下以本機win10系統爲例詳細記錄:
【需要的環境】
java環境jdk
mycat-server
mycat-eye
zookeeper
navicat 客戶端 navicat for mysql
mysql 環境(5.5以上)
【下載MyCat】
下載地址:https://github.com/MyCATApache/Mycat-download,我下載的是Mycat-server-1.6版本;
【配置&安裝】
下載完成解壓到你想要的目錄,解壓後的目錄說明:
bin執行文件
conf配置文件
lib依賴包
logs日誌
conf目錄中主要文件
rule.xml分片規則配置文件
schema.xml數據庫配置文件
server.xml系統參數配置文件
然後,使用管理員權限打開cmd併到MyCat的安裝目錄,切換到mycat/bin目錄;執行startup_nowrap.bat,一般情況都可以啓動成功。因這這個時候所有的配置都是默認的。
接下來就需要按我們的業務需要來配置MyCat了,這裏建議先不要按網上的資料馬上開始貼過來配置,而是先花點時間瞭解一下它的分片規則,個人覺得這個很重要。
假設我們有3個數據庫實例:
db1:localhost:3306 nick_mysqlcluster_test_1
db2:localhost:3306 nick_mysqlcluster_test_2
db3:localhost:3306 nick_mysqlcluster_test_3
同主機db1,db2,db3中 t_test表 爲分片表 以CreateTime爲分片字段進行數據分片;
CREATE TABLE `t_test` (
`Id` varchar(36) NOT NULL,
`Name` varchar(64) NOT NULL,
`CreateTime` datetime NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
使用Navicat Premium 12或其他工具聯上你的MySQL創建三個庫(nick_mysqlcluster_test_1、2、3),每個庫中一個表(t_test)每個庫中的t_test表結構是一樣的。
【rule.xml分片規則配置】
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="sharding-by-date-rule">
<rule>
<columns>CreateTime</columns>
<algorithm>sharding-by-date</algorithm>
</rule>
</tableRule>
<function name="sharding-by-date" class="io.mycat.route.function.PartitionByDate">
<property name="dateFormat">yyyy-MM-dd</property>
<property name="sBeginDate">2019-10-01</property>
<property name="sPartionDay">10</property>
</function>
</mycat:rule>
注:這裏配置的意思爲從2019-10-01開始,每10天一個分片。其他的分片策略請看官網。
【schema.xml數據庫配置文件】
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="t_test" rule="sharding-by-date-rule" dataNode="dn1,dn2,dn3"/>
<table name="t_test2" type="global" primaryKey="Id" dataNode="dn1"/>
</schema>
<dataNode name="dn1" dataHost="localhost1" database="nick_mysqlcluster_test_1"/>
<dataNode name="dn2" dataHost="localhost1" database="nick_mysqlcluster_test_2"/>
<dataNode name="dn3" dataHost="localhost1" database="nick_mysqlcluster_test_3"/>
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="localhost:3306" user="root" password="******"/>
</dataHost>
</mycat:schema>
【server.xml系統參數配置文件】
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="defaultSqlParser">druidparser</property>
<property name="useHandshakeV10">1</property>
<property name="mutiNodeLimitType">1</property>
<property name="charset">utf8</property>
<property name="serverPort">8066</property>
<property name="managerPort">9066</property>
</system>
<user name="root">
<property name="password">nickhuang</property>
<property name="schemas">TESTDB</property>
</user>
<user name="user">
<property name="password">testuser</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
如果環境都配置好同時MyCat的重要三個文件也配置完成,看一下成果吧:管理員權限打開cmd併到MyCat的安裝目錄,切換到mycat/bin目錄;執行mycat start看看是否可以執行成功。
如果不成功請檢查以下原因:
先查看日誌:在哪找?logs/wrapper.log文件!記到哦。
1.MySQL的版本問題:最初我裝的是8.0.16版本,一直無法啓動,後來才知道目前爲止MyCat不支持8.0,當然有辦法解決,這裏不囉嗦這些,改裝5.7.27版本,沒有問題;
2.如果jdk1.8,請修改conf/wrapper.conf文件:wrapper.java.additional.3=-XX:MaxPermSize=64M更改爲:wrapper.java.additional.3=-XX:MaxMetaspaceSize=64M
3.如果配置的是其他分片策略,可能會出現不同的問題 ,這裏要一一排查,我也無法一下寫全,這裏只記錄這兩個比較重要的問題 。
OK,這時候再start,啓動成功。
程序中如何使用呢?
這一部分網上的文章真不多,而且有也完全不可以使用,由於我們分庫分表的這個服務使用的ORM是efcore,很多人說要用Pomelo.EntityFrameworkCore.MyCat,我也嘗試了很多次,無果。這裏記錄一下真實可用的方案:
重要:只安裝包mysql.data.entityframework.core包,其他的都不要安裝,包括Pomelo.EntityFrameworkCore.MyCat!!!
2.DbContext
public class SampleContext : DbContext
{
public SampleContext(DbContextOptions<SampleContext> options) : base(options)
{
}
public DbSet<User> User { get; set; }
}
3.Startup
services.AddDbContext<SampleContext>(options => options.UseMySQL(Configuration.GetConnectionString("DefaultConnection")));
4.appsettings.json
"ConnectionStrings": {
"DefaultConnection": "server=localhost;port=8066;uid=root;pwd=******;database=TESTDB"
}
以前的業務代碼都不用改。只是在這裏,我們以前直接MySQL,現在的一個變化是轉而連接MyCat。
跑起來,用Postman試一下吧,分別寫入CreateTime爲:2019-10-08、2019-10-12、2019-10-19或其他,看看他們會寫到哪個庫的t_test表中,是不是和我們預期的一樣呢?
先寫到這裏,以後有時間,繼續完善其他功能。如果有小夥伴感興趣,可以加Q38095589交流。
也請大牛多指點,感謝!