springboot+mycat 分表分庫

前言

對於業務量越來越大的時候,單表數據超過幾千萬,甚至上億時,一張表裏面查詢真的會很費時。而在分佈式系統中,分表分庫也是常用的一種解決此類瓶頸的手段。今天就選用springboot+mycat簡單聊下。

  • 什麼是mycat?

      1. 一個徹底開源的,面向企業應用開發的大數據庫集羣
      2. 支持事務、ACID、可以替代MySQL的加強版數據庫
      3. 一個可以視爲MySQL集羣的企業級數據庫,用來替代昂貴的Oracle集羣
      4. 一個融合內存緩存技術、NoSQL技術、HDFS大數據的新型SQL Server
      5. 結合傳統數據庫和新型分佈式數據倉庫的新一代企業級數據庫產品
      6. 一個新穎的數據庫中間件產品
  • 爲什麼要用mycat?

       支持MySQL、Oracle、DB2、SQL Server、PostgreSQL等DB的常見SQL語法
       遵守Mysql原生協議,跨語言,跨平臺,跨數據庫的通用中間件代理
       基於心跳的自動故障切換,支持讀寫分離,支持MySQL主從,以及galera cluster集羣。
       支持Galera for MySQL集羣,Percona Cluster或者MariaDB cluster
       基於Nio實現,有效管理線程,解決高併發問題。
       支持數據的多片自動路由與聚合,支持sum,count,max等常用的聚合函數,支持跨庫分頁。
       支持單庫內部任意join,支持跨庫2表join,甚至基於caltlet的多表join。
       支持通過全局表,ER關係的分片策略,實現了高效的多表join查詢。
       支持多租戶方案。
       支持分佈式事務(弱xa)。
       支持XA分佈式事務(1.6.5)。
       支持全局序列號,解決分佈式下的主鍵生成問題。
       分片規則豐富,插件化開發,易於擴展。
       強大的web,命令行監控。
       ...
       
centos7安裝下載mycat
  1. centos7安裝mycat
    安裝mycat比較簡單,我這邊也詳細說明一下:

     #下載: 
     wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
     #解壓
     tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
     #授權
     chmod -R 777 mycat
     #環境變量添加:
     vi /etc/profile
     #在裏面添加:
     export MYCAT_HOME=/crawler/mycat/mycat   ##自己的安裝路徑
     export PATH=$PATH:$MYCAT_HOME/bin  
     #使環境變量生效
     source /etc/profile
     #注意:
     #Linux 下部署安裝 MySQL,默認不忽略表名大小寫,需要手動到/etc/my.cnf 下配置:
     lower_case_table_names=1
     
  2. 前期準備
    ps:mycat需要配置java_home ,就算安裝了java如果沒有配置java_home.還是會拋沒有找到java_home的錯,在此,我們檢查一下有沒有配置,若沒有配置,請按以下步驟操作:

       A 確定java安裝路徑
          
      1. 終端輸入:
         which java
       輸出爲:
         /usr/bin/java
      2. 終端輸入:
         ls -lr /usr/bin/java
       輸出爲: 
          /usr/bin/java -> 
       3. 終端輸入
           ls -lrt /etc/alternatives/java
        輸出:    
           /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64/jre/bin/java
    

至此,我們確定java的安裝目錄爲: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64

 B 配置JAVA_HOME

1. 打開配置環境變量的文件
vi /etc/profile
2. 添加以下配置:
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

:wq保存退出。
3. 讓配置生效
source  /etc/profile
4. 測試配置結果
echo $JAVA_HOME 

3.配置關鍵配置

a:配置schema.xml

  <?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">

<mycat:schema xmlns:mycat="http://io.mycat/">
 
   <schema name="mycatDatabase" checkSQLschema="false" sqlMaxLimit="100">
           <table name="user" primaryKey="id" dataNode="dn01,dn02" rule="rule1" />  
   </schema>
   
   <!-- 設置dataNode 對應的數據庫,及 mycat 連接的地址dataHost -->  
   <dataNode name="dn01" dataHost="dh01" database="db01" />  
   <dataNode name="dn02" dataHost="dh01" database="db02" />   
   
   <!-- mycat 邏輯主機dataHost對應的物理主機.其中也設置對應的mysql登陸信息 -->  
   <dataHost name="dh01" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native">  
           <heartbeat>select user()</heartbeat>  
           <writeHost host="server1" url="127.0.0.1:3306" user="root" password="這裏是你的密碼">  
                      <!-- <readHost host="server1" url="cd-cdb-5p62gwp2.sql.tencentcdb.com:62918" user="root" password="123456"/>  --> 
                 </writeHost>
   </dataHost> 
</mycat:schema>

b:配置rule.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License"); 
    - you may not use this file except in compliance with the License. - You 
    may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 
    - - Unless required by applicable law or agreed to in writing, software - 
    distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT 
    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the 
    License for the specific language governing permissions and - limitations 
    under the License. -->
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
   <tableRule name="rule1"> <!--這個name和schema裏面對應-->
       <rule>
           <columns>id</columns>
           <algorithm>mod-long</algorithm>
       </rule>
   </tableRule>
   <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
       <!-- how many data nodes -->
       <property name="count">2</property>
   </function>
</mycat:rule>

c:配置server.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License"); 
    - you may not use this file except in compliance with the License. - You 
    may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 
    - - Unless required by applicable law or agreed to in writing, software - 
    distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT 
    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the 
    License for the specific language governing permissions and - limitations 
    under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
    <system>
    <property name="useSqlStat">0</property>  <!-- 1爲開啓實時統計、0爲關閉 -->
    <property name="useGlobleTableCheck">0</property>  <!-- 1爲開啓全加班一致性檢測、0爲關閉 -->

        <property name="sequnceHandlerType">2</property>
      <!--  <property name="useCompression">1</property>--> <!--1爲開啓mysql壓縮協議-->
        <!--  <property name="fakeMySQLVersion">5.6.20</property>--> <!--設置模擬的MySQL版本號-->
    <!-- <property name="processorBufferChunk">40960</property> -->
    <!-- 
    <property name="processors">1</property> 
    <property name="processorExecutor">32</property> 
     -->
        <!--默認爲type 0: DirectByteBufferPool | type 1 ByteBufferArena-->
        <property name="processorBufferPoolType">0</property>
        <!--默認是65535 64K 用於sql解析時最大文本長度 -->
        <!--<property name="maxStringLiteralLength">65535</property>-->
        <!--<property name="sequnceHandlerType">0</property>-->
        <!--<property name="backSocketNoDelay">1</property>-->
        <!--<property name="frontSocketNoDelay">1</property>-->
        <!--<property name="processorExecutor">16</property>-->
        <!--
            <property name="serverPort">8066</property> <property name="managerPort">9066</property> 
            <property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property> 
            <property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
        <!--分佈式事務開關,0爲不過濾分佈式事務,1爲過濾分佈式事務(如果分佈式事務內只涉及全局表,則不過濾),2爲不過濾分佈式事務,但是記錄分佈式事務日誌-->
        <property name="handleDistributedTransactions">0</property>
        
            <!--
            off heap for merge/order/group/limit      1開啓   0關閉
        -->
        <property name="useOffHeapForMerge">1</property>

        <!--
            單位爲m
        -->
        <property name="memoryPageSize">1m</property>

        <!--
            單位爲k
        -->
        <property name="spillsFileBufferSize">1k</property>

        <property name="useStreamOutput">0</property>

        <!--
            單位爲m
        -->
        <property name="systemReserveMemorySize">384m</property>


        <!--是否採用zookeeper協調切換  -->
        <property name="useZKSwitch">true</property>


    </system>
    
    <!-- 全局SQL防火牆設置 -->
    <!-- 
    <firewall> 
       <whitehost>
          <host host="127.0.0.1" user="mycat"/>
          <host host="127.0.0.2" user="mycat"/>
       </whitehost>
       <blacklist check="false">
       </blacklist>
    </firewall>
    -->
    
    <user name="crawler"> <!-- 連接mycat的用戶名-->
        <property name="password">123456</property> <!-- 連接mycat的密碼-->
        <property name="schemas">mycatDatabase</property>  <!-- 邏輯數據庫名,這裏會和schema.xml中的配置關聯,多個用逗號分開 -->
        <property name="readOnly">false</property>
    </user>

</mycat:server>

此時,我們運行mycat : mycat/bin/startup_nowrap.sh
如果是阿里雲或者其他雲服務器,需要把mycat的端口打開,默認端口是8066
此時,我們可以看一下日誌:
mycat/logs/..

若沒什麼問題,那麼就可以在springboot上做集成了
ps:我們必須在上面所涉及到的地方建兩個庫哦: 如上面我建的是db01 db02

springboot集成mycat
 spring:
  datasource:
    url: jdbc:mysql://www.iamcrawler.cn:8066/mycatDatabase?serverTimezone=Asia/Shanghai
    username: crawler
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver

service

/**
 * create by liuliang
 * on 2019-07-30  17:16
 */
@Service
public class MycatUserService extends ServiceImpl<MycatUserMapper, MycatUser> {
    
    public List<MycatUser> getUsers(){
        List<MycatUser> list = this.list(new QueryWrapper<>());
        return list;
    }

}

controller

/**
 * create by liuliang
 * on 2019-07-30  17:17
 */
@RestController
@RequestMapping("/mycat/user")
public class MyCatUserController {

    @Autowired
    private MycatUserService userService;


    @PostMapping
    public ResponseEntity insertUser(@RequestBody MycatUser mycatUser){
        return ResponseEntity.ok(userService.save(mycatUser));
    }

    @GetMapping
    public ResponseEntity getUsers(){
        return ResponseEntity.ok(userService.getUsers());
    }

}


這個時候我們啓動程序,先後插入兩條數據:

localhost:9090/mycat/user  post
 {
    "id":"10",
    "name":"zhangsan"
}
 localhost:9090/mycat/user  post
 {
    "id":"11",
    "name":"lisi"
}

數據庫看的時候,發現已經進入了兩個不同的庫。
而我們查詢的時候:


   localhost:9090/mycat/user  get
    [
    {
        "id": 11,
        "name": "lisi"
    },
    {
        "id": 10,
        "name": "zhangsan"
    }
]

可以看到是,數據都查詢出來了,mycat分庫生效

ps:如果各位有項目使用的是liquibase,那麼與mycat集成的時候會拋錯,原因是因爲liquibase需要簡歷changelog表,而使用的庫是mycatDatabase ,這個是mycat的連接,而不是真實數據庫的連接...

最後,碼字不易,轉載複製請指明原創https://segmentfault.com/a/11...,違者必究...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章