1. 程式人生 > >mycat分表分庫 減輕資料庫壓力

mycat分表分庫 減輕資料庫壓力

版權宣告:    https://blog.csdn.net/zhydream77/article/details/82148457
目錄

資料庫分片 

準備環境

配置過程

主機51和主機52的配置 (這裡只寫一臺資料庫)

配置mycat伺服器

啟動服務

測試MyCAT

 
資料庫分片 

如何解決 併發訪問壓力,單表壓力過大的問題?

mycat的介紹:

什麼是分庫分表?
 通過某種特定條件,將存放在一個數據庫 ( 主機 ) 中的資料,分散存放到多個數據庫 ( 主機 ) 中。
已達到分散單臺裝置負載的效果,即分庫分表。 資料的切分根據其切分規則的型別,分為 2 種切分模

垂直分割 ( 縱向 ) 和 水平分割 ( 橫向 )

垂直分割
• 縱向切分
把單一的表,拆分成多個表,並分散到不同的資料庫( 主機 ) 上。
一個數據庫由多個表構成,每個表對應不同的業務,可以按照業務對錶進行分類,將其分佈到不同的資料庫 ( 主機 ) 上,實現專庫專用,讓不同的庫 ( 主機 ) 分擔不同的業務。

水平分割
• 橫向切分
按照表中某個欄位的某種規則,把向表中寫入的記錄分散到多個庫 ( 主機 ) 中。
簡單來說,就是按照資料行切分,將表中的某些行儲存到指定的資料庫 ( 主機 ) 中。

軟體介紹

Mycat 是基於 Java 的分散式資料庫系統中間層,為
高併發下的分散式提供解決方案
– 支援 JDBC 形式連線
– 支援 MySQL 、 Oracle 、 Sqlserver 、 Mongodb 等
– 提供資料讀寫分離服務
– 可以實現資料庫伺服器的高可用
– 提供資料分片服務
– 基於阿里巴巴 Cobar 進行研發的開源軟體
– 適合資料大量寫入資料的儲存需求

分片規則
• mycat 服務提供 10 種分片規則。
– 1 列舉法 sharding-by-intfile
– 2 固定分片 rule1
– 3 範圍約定 auto-sharding-long
– 4 求模法 mod-long
– 5 日期列分割槽法 sharding-by-date
– 6 通配取模 sharding-by-pattern
– 7ASCII 碼求模通配 sharding-by-prefixpattern
– 8 程式設計指定 sharding-by-substring
– 9 字串拆分 hash 解析 sharding-by-stringhash
– 10 一致性 hash sharding-by-murmur

工作過程

 

當 Mycat 收到一個 SQL 時
– 會先解析這個 SQL 查詢涉及到的表,然後看此表的定義
– 如果有分片規則,則獲取到 SQL 裡分片欄位的值,並匹配分片函式,得到該SQL 對應的分片列表
– 然後將 SQL 發往這些分片去執行,最後收集和處理所有分片返回的結果資料,並輸出到客戶端
以 select * from Orders where prov=? 語句為例,查到 prov=wuhan ,
按照分片函式, wuhan 返回 dn1 ,於是 SQL 就發給了 MySQL1 ,去
取 DB1 上的查詢結果,並返回給使用者。
如果上述 SQL 改為 select * from Orders where prov in
(‘wuhan’,‘beijing’) ,那麼, SQL 就會發給 ySQL1 與 MySQL2 去執行,
然後結果集合並後輸出給使用者。但通常業務中我們的 SQL 會有 Order
By 以及 Limit 翻頁語法,此時就涉及到結果集在 Mycat 端的二次處
理。

準備環境
192.168.4.51 mycat分片  

192.168.4.52 dn1

192.168.4.53 dn2

192.168.4.54 客戶端 

配置過程

主機51和主機52的配置 (這裡只寫一臺資料庫)

[[email protected] ~]# tar -xaf mysql-5.7.17.tar
[[email protected] ~]# ls
mysql-community-client-5.7.17-1.el7.x86_64.rpm
mysql-community-common-5.7.17-1.el7.x86_64.rpm
mysql-community-devel-5.7.17-1.el7.x86_64.rpm
mysql-community-embedded-5.7.17-1.el7.x86_64.rpm
mysql-community-embedded-compat-5.7.17-1.el7.x86_64.rpm
mysql-community-embedded-devel-5.7.17-1.el7.x86_64.rpm
mysql-community-libs-5.7.17-1.el7.x86_64.rpm
mysql-community-libs-compat-5.7.17-1.el7.x86_64.rpm
mysql-community-minimal-debuginfo-5.7.17-1.el7.x86_64.rpm
mysql-community-server-5.7.17-1.el7.x86_64.rpm
mysql-community-test-5.7.17-1.el7.x86_64.rpm
[[email protected] ~]# yum install  mysql-comm*
[[email protected] ~]# systemctl restart mysqld
[[email protected] ~]# cat /var/log/mysqld.log  | grep password
2018-08-28T01:45:31.046087Z 1 [Note] A temporary password is generated for [email protected]: nz!4X3-OsSOe
[[email protected] ~]# vim /etc/my.cnf  ----新增(密碼安全策略)
[mysqld]
validate_password_policy=0
validate_password_length=6
[[email protected] ~]# systemctl restart mysqld
[[email protected] ~]# mysql -uroot -p'nz!4X3-OsSOe'
[[email protected] ~]# mysql -uroot -p'123456'

配置mycat伺服器

[[email protected] ~]# rpm -qa | grep -i jdk
java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64
java-1.8.0-openjdk-headless-1.8.0.131-11.b12.el7.x86_64
copy-jdk-configs-2.2-3.el7.noarch
[[email protected] ~]# ls
Mycat-server-1.4-beta-20150604171601-linux.tar.gz
[[email protected] ~]# rpm -qa | grep -i jdk
java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64
java-1.8.0-openjdk-headless-1.8.0.131-11.b12.el7.x86_64
copy-jdk-configs-2.2-3.el7.noarch
[[email protected] ~]# tar -xaf Mycat-server-1.4-beta-20150604171601-linux.tar.gz
[[email protected] ~]# cd mycat/
[[email protected] mycat]# ls
bin  catlet  conf  lib  logs  version.txt
[[email protected] ~]# mv mycat/ /usr/local/
2.工作目錄
[[email protected] ~]# ls /usr/local/
bin  etc  games  include  lib  lib64  libexec  mycat  sbin  share  src
3.修改配置檔案
[[email protected] ~]# cd /usr/local/mycat/
[[email protected] mycat]# cd conf/
[[email protected] conf]# ls
autopartition-long.txt       myid.properties                       sequence_time_conf.properties
auto-sharding-long.txt       partition-hash-int.txt                server.xml
auto-sharding-rang-mod.txt   partition-range-mod.txt               sharding-by-enum.txt
cacheservice.properties      rule.xml                              wrapper.conf
ehcache.xml                  schema.xml                            zkconf
index_to_charset.properties  sequence_conf.properties              zkdownload
log4j2.xml                   sequence_db_conf.properties
migrateTables.properties     sequence_distributed_conf.properties
[[email protected] conf]# cp server.xml server.xml.bak  ---做備份
[[email protected] conf]# cp schema.xml schema.xml.bak  ----做備份
[[email protected] conf]# vim rule.xml

 [[email protected] conf]# cat /usr/local/mycat/conf/server.xml  #定義連線客戶端連線mycat服務使用的使用者名稱和密碼及邏輯庫的名字
<?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://org.opencloudb/">
    <system>
    <property name="defaultSqlParser">druidparser</property>
      <!--  <property name="useCompression">1</property>--> <!--1為開啟mysql壓縮協議-->
    <!-- <property name="processorBufferChunk">40960</property> -->
    <!-- 
    <property name="processors">1</property> 
    <property name="processorExecutor">32</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="mutiNodeLimitType">1</property> 0:開啟小數量級(預設) ;1:開啟億級資料排序
            <property name="mutiNodePatchSize">100</property> 億級數量排序批量
            <property name="processors">32</property> <property name="processorExecutor">32</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> -->
    </system>

    <user name="test">  #連線mycat服務時使用的使用者名稱 test 
        <property name="password">test</property>   #使用test使用者連線mycat使用者時使用的密碼
        <property name="schemas">TESTDB</property>  #連線上mycat服務後,可以看到的庫名多個時,使用逗號分隔 (是邏輯上的庫名)
    </user>

    <user name="user"> 
        <property name="password">user</property>
        <property name="schemas">TESTDB</property>
        <property name="readOnly">true</property> #定義只讀許可權,使用定義的user使用者連線mycat服務後只有讀記錄的許可權
    </user>
    <!-- <cluster> <node name="cobar1"> <property name="host">127.0.0.1</property> 
        <property name="weight">1</property> </node> </cluster> -->
    <!-- <quarantine> <host name="1.2.3.4"> <property name="user">test</property> 
        </host> </quarantine> -->

</mycat:server>

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 [[email protected] conf]# cat /usr/local/mycat/conf/schema.xml 
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">

          <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"> #邏輯庫名 要與server.xml定義的一樣
                 
         
                 <table name="travelrecord" dataNode="dn1,dn2" rule="auto-sharding-long" />  #定義分片的表
                
         
                 <table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2" />  #定義分片的表
                
        
                 <table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2" /> #定義分片的表
                 
        
                 <table name="hotnews" primaryKey="ID" dataNode="dn1,dn2" rule="mod-long" /> #定義分片的表
                
        
                 <table name="employee" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile" />   #定義分片的表
                
        
                 <table name="customer" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile" /> #定義分片的表
                 
          </schema>
    
        <dataNode name="dn1" dataHost="c1" database="db1" /> 
        #定義分片使用的庫,所在的物理主機 ,真正儲存資料的db1庫在物理主機c1上
    
        <dataNode name="dn2" dataHost="c2" database="db2" /> 
        #定義分片使用的庫,所在的物理主機 ,真正儲存資料的db2庫在物理主機c2上
    
         #指定c1名稱主機對應的ip地址
    <dataHost name="c1" maxCon="1000" minCon="10" balance="0"
        writeType="0" dbType="mysql" dbDriver="native" > 
        <heartbeat>select user()</heartbeat>
                <writeHost host="hostM1" url="192.168.4.55:3306" user="admin"    
            password="123456">   #訪問資料時 mycat服務連線資料庫伺服器時使用的使用者名稱和密碼
        </writeHost>
    </dataHost>

         #指定c2名稱主機對應的ip地址
    <dataHost name="c2" maxCon="1000" minCon="10" balance="0"
        writeType="0" dbType="

[[email protected] ~]# cat /usr/local/mycat/conf/server.xml  #定義連線客戶端連線mycat服務使用的使用者名稱和密碼及邏輯庫的名字
<?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://org.opencloudb/">
    <system>
    <property name="defaultSqlParser">druidparser</property>
      <!--  <property name="useCompression">1</property>--> <!--1為開啟mysql壓縮協議-->
    <!-- <property name="processorBufferChunk">40960</property> -->
    <!-- 
    <property name="processors">1</property> 
    <property name="processorExecutor">32</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="mutiNodeLimitType">1</property> 0:開啟小數量級(預設) ;1:開啟億級資料排序
            <property name="mutiNodePatchSize">100</property> 億級數量排序批量
            <property name="processors">32</property> <property name="processorExecutor">32</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> -->
    </system>

    <user name="test">  #連線mycat服務時使用的使用者名稱 test 
        <property name="password">test</property>   #使用test使用者連線mycat使用者時使用的密碼
        <property name="schemas">TESTDB</property>  #連線上mycat服務後,可以看到的庫名多個時,使用逗號分隔 (是邏輯上的庫名)
    </user>

    <user name="user"> 
        <property name="password">user</property>
        <property name="schemas">TESTDB</property>
        <property name="readOnly">true</property> #定義只讀許可權,使用定義的user使用者連線mycat服務後只有讀記錄的許可權
    </user>
    <!-- <cluster> <node name="cobar1"> <property name="host">127.0.0.1</property> 
        <property name="weight">1</property> </node> </cluster> -->
    <!-- <quarantine> <host name="1.2.3.4"> <property name="user">test</property> 
        </host> </quarantine> -->

</mycat:server>

啟動服務

  [[email protected] conf]# sed -n  '4,5p' /usr/local/mycat/conf/wrapper.conf 
  # Java Application
  wrapper.java.command=java
  [[email protected] conf]# which java
  /usr/bin/java

 [[email protected] conf]# echo  "export PATH=/usr/local/mycat/bin"  >> /etc/profile
  [[email protected] conf]#source  /etc/profile

  [[email protected] conf]# mycat  --help
 Usage: /usr/local/mycat/bin/mycat { console | start | stop | restart | status | dump }

  [[email protected] conf]# mycat  start
 Starting Mycat-server...
  [[email protected] conf]# netstat -utnalp  | grep :8066
 tcp6       0      0 :::8066                 :::*                    LISTEN      4524/java           


測試MyCAT

[[email protected] ~]# mysql -h192.168.4.56 -P8066 -utest -ptest  //客戶端連線mycat伺服器,儲存資料
MySQL [(none)]> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB   |
+----------+
1 row in set (0.00 sec)
MySQL [(none)]> use TESTDB;
MySQL [TESTDB]> show tables;
+------------------+
| Tables in TESTDB |
+------------------+
| company          |
| customer         |
| employee         |
| goods            |
| hotnews          |
| travelrecord     |
+------------------+
6 rows in set (0.00 sec)

MySQL [TESTDB]> MySQL [TESTDB]> create table employee( id int not null primary key, name varchar(100), sharding_id int not null );

MySQL [TESTDB]> MySQL [TESTDB]> insert  into  employee(id,name,sharding_id)values(1,"bob",10000),(2,"lucy",10010),(3,"alice",10000),(4,"jerry",10010);

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mysql> select  @@hostname;
+------------+
| @@hostname |
+------------+
| c1         |
+------------+
1 row in set (0.00 sec)

mysql> select  * from employee;
Empty set (0.00 sec)

mysql> select  * from employee;
+----+-------+-------------+
| id | name  | sharding_id |
+----+-------+-------------+
|  1 | bob   |       10000 |
|  3 | alice |       10000 |
+----+-------+-------------+
2 rows in set (0.00 sec)
++++++++++++++++++++++++++++++++++++++++++++++
mysql> select @@hostname;
+------------+
| @@hostname |
+------------+
| c2         |
+------------+
1 row in set (0.00 sec)

mysql> select * from employee;
Empty set (0.00 sec)

mysql> select * from employee;
+----+-------+-------------+
| id | name  | sharding_id |
+----+-------+-------------+
|  2 | lucy  |       10010 |
|  4 | jerry |       10010 |
+----+-------+-------------+
2 rows in set (0.00 sec)

主機52

[[email protected] ~]# mysql -uroot -p123456

mysql> use db1
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| employee      |
+---------------+
1 row in set (0.00 sec)

mysql> select * from employee
    -> ;
+----+-------+-------------+
| id | name  | sharding_id |
+----+-------+-------------+
|  1 | bob   |       10000 |
|  3 | alice |       10000 |
+----+-------+-------------+
2 rows in set (0.00 sec)

主機53

[[email protected] ~]# mysql -uroot -p123456

mysql> select * from employee;
ERROR 1046 (3D000): No database selected
mysql> use db2
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from employee ;
+----+-------+-------------+
| id | name  | sharding_id |
+----+-------+-------------+
|  2 | lucy  |       10010 |
|  4 | jerry |       10010 |
+----+-------+-------------+
2 rows in set (0.00 sec)
 

原文:https://blog.csdn.net/zhydream77/article/details/82148457