分庫分表

分庫分表

  • 關係型數據庫和NoSQL

    非關係型數據庫: key-value: redis 、memcache ;java

    面向文檔: mongoDB mysql

    面向列: HBaseios

    數據切分git

    mycatgithub

    TDDLredis

    Sharding-JDBC算法

    cobarsql

  1. 對於存儲層的壓力知道如何去提供解決方案和思路
  2. 對分庫分表的經常使用手段有全面瞭解
  3. 瞭解Mysql的主從及binlog
  4. 知道Mycat及其餘類似的中間件

爲何要分庫分表

超大容量問題shell

  • 訂單表數據量過大數據庫

    • 單表處理能力有瓶頸

性能問題

  • 單一數據庫解決全部應用節點

    • 單一數據庫有性能極限

如何去作到

垂直切分、 水平切分

  1. 垂直分庫

    1. 解決的是表過多的問題
    2. 不一樣的表放在不一樣的庫中

      1. 好比說訂單相關的放在訂單庫中
  2. 垂直分表

    1. 解決單表列過多的問題
    2. 列多的表拆分紅多個列少的表

      1. 好比說商 品表拆分

        1. 經過關聯關係維持數據

水平切分

  • 大數據表拆成小表

常見的拆分策略

拆分若是所有放在一個庫中,可能會有性能問題。

​ 可能把部分表放在不一樣的數據庫中

拆分維度選擇的數據很是重要

垂直拆分

​ er分片

水平拆分

  • 一致性hash
  • 範圍切分

    • 能夠按照ID
  • 日期拆分

拆分之後帶來的問題

跨庫join的問題

select a.x ,b.y from a,b on a.id=b.id

  1. 設計的時候考慮到應用層的join問題。

    1. 拆分的時候考慮好
  2. 在服務層去作調用

    A服務裏查詢到一個list

    直接經過接口查詢

/**
    *批量查詢不要這樣使用
**/
for(list){
  bservice.select(list);
}
  1. 全局表

    1. 數據變動比較少的基於全局應用的表
    2. 或者抽離公共服務
  2. 作字段冗餘(空間換時間的作法)

    ​ 訂單表須要展現,商家id 商家名稱(由於訂單表和商家表是一對一的關係),那麼查詢的時候可能每一次都須要爲了查詢商家名稱,能夠作商家名稱字段冗餘

    ​ 商家名稱變動解決辦法

    1. 定時任務
    2. 任務通知

跨分片數據排序分頁

​ 在應用層作拼接

惟一主鍵問題

​ 用自增id作主鍵,多表狀況下自增id會重複

解決方案

  • UUID 性能比較低

    • 值比較長
    • 致使索引比較大
    • 性能比較低
  • snowflake (雪花算法)

    • 時間序列
    • 機器標誌
    • 技術順序號
    • 一塊兒組成的完成id
  • mongoDB

    • ObjectId
  • zookeeper

    • 有序節點,從1開始遞增
  • redis自增

    • incr
  • 數據庫表

    • 專門一張表來獲取id

分佈式事務問題

​ 多個數據庫表之間保證原子性

​ 性能問題; 互聯網公司用強一致性分佈式事務比較少,通常使用最終一致性,或者軟事物來解決

​ 分庫分表最難的在於業務的複雜度;

​ 前提: 水平分表的前提是已經存在大量的業務數據。而這個業務數據已經滲透到了各個應用節點

如何權衡當前公司的存儲須要優化

1. 提早規劃(主鍵問題解決、 join問題)

2. 當前數據單表超過1000W、天天的增加量持續上升

Mysql的主從

絕大部分都是寫少讀多的操做,能夠作讀寫分離,多個讀庫作壓力釋放

讀庫能夠實現負載均衡

image-20190505192959801

數據庫的版本5.7版本

安裝之後文件對應的目錄

mysql的數據文件和二進制文件: /var/lib/mysql/

mysql的配置文件: /etc/my.cnf

mysql的日誌文件: /var/log/mysql.log

6 爲master

  1. 建立一個用戶repl,而且容許其餘服務器能夠經過該用戶遠程訪問master,經過該用戶去讀取二進制數據,實現數據同步
Create user repl identified by 'repl';

repl用戶必須具備REPLICATION SLAVE權限,除此以外其餘權限都不須要

GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'repl' ;

2.修改6 etc/my.cnf配置文件,在[mysqld] 下添加以下配置

log-bin=mysql-bin #啓用二進制日誌文件
server-id=6 #服務器惟一ID

3.重啓數據庫

systemctl restart mysqld

4.登陸到數據庫,經過show master status 查看master的狀態信息

118 爲slave

  1. 修改118 my.cnf配置文件, 在[mysqld]下增長以下配置
server-id=118  #服務器id,惟一

relay-log=slave-relay-bin #中繼日誌,保存master同步過來的信息

relay-log-index=slave-relay-bin.index

read_only=1
  1. 重啓數據庫: systemctl restart mysqld
  2. 鏈接到數據庫客戶端,經過以下命令創建同步鏈接
change master to master_host='116.62.221.6', master_port=3306,master_user='repl',master_password='repl',master_log_file='mysql-bin.000003',master_log_pos=429;

master_log_pos 表示從主節點哪一個位置開始讀,

master_log_file這兩個部分從master的show master status能夠找到對應的值,不能隨便寫。

  1. 執行 start slave
  2. show slave status\G;

    1. 查看slave服務器狀態,當以下兩個線程狀態爲yes,表示主從複製配置成功

      Slave_IO_Running=Yes
      Slave_SQL_Running=Yes

主從同步的原理

image-20190505204753810

  1. master記錄二進制日誌。在每一個事務更新數據完成以前,master在二日誌記錄這些改變。MySQL將事務串行的寫入二進制日誌,即便事務中的語句都是交叉執行的。在事件寫入二進制日誌完成後,master通知存儲引擎提交事務

    1. slave將master的binary log拷貝到它本身的中繼日誌。首先,slave開始一個工做線程——I/O線程。I/O線程在master上打開一個普通的鏈接,而後開始binlog dump process。Binlog dump process從master的二進制日誌中讀取事件,若是已經跟上master,它會睡眠並等待master產生新的事件。I/O線程將這些事件寫入中繼日誌
    2. SQL線程從中繼日誌讀取事件,並重放其中的事件而更新slave的數據,使其與master中的數據一致

binlog: 用來記錄mysql的數據更新或者潛在更新(update xxx where id=x effect row 0);

文件內容存儲:/var/lib/mysql

mysqlbinlog --base64-output=decode-rows -v mysql-bin.000001 查看binlog的內容

show binlog events in 'mysql-bin.000001'查看binlog的日誌,不須要看內容

binlog的格式

查看當前日誌模式

show variables like '%log%' -> binlog_format

statement :

​ 基於sql語句的模式。update table set name =」」; effect row 1000; uuid、now() other function

row: (默認)

​ 基於行模式; 存在1000條數據變動; 記錄修改之後每一條記錄變化的值

mixed:

​ 混合模式,由mysql自動判斷處理

修改binlog_formater,經過在mysql客戶端輸入以下命令能夠修改

set global binlog_format='row/mixed/statement';

或者在

vim /etc/my.cnf 的[mysqld]下增長binlog_format='mixed'

主從同步的延時問題

在這裏插入圖片描述
一主多從或者雙主

網絡延遲比較大

磁盤的讀寫

主從同步延遲是怎麼產生的

  1. 當master庫tps比較高的時候,產生的DDL數量超過slave一個sql線程所能承受的範圍,或者slave的大型query語句產生鎖等待
  2. 網絡傳輸: bin文件的傳輸延遲
  3. 磁盤的讀寫耗時:文件通知更新、磁盤讀取延遲、磁盤寫入延遲

解決方案

  1. 在數據庫和應用層增長緩存處理,優先從緩存中讀取數據

    1. 從緩存中取,同步後而後再從slave中取
  2. 減小slave同步延遲,能夠修改slave庫sync_binlog屬性;

    sync_binlog=0 設置爲0執行ddl binlog不會立馬刷新到文件中,而是經過文件系統調度刷新

    ​ 文件系統來調度把binlog_cache刷新到磁盤

sync_binlog=n 等於n表示執行n個事物刷新

  1. 增長延時監控

    Nagios作網絡監控

    mk-heartbeat 心跳監控

    經過監控作報警

  2. Mysql的主從配置
  3. 瞭解binlog及主從複製原理

MyCat

簡介

地址:http://www.mycat.io/

https://github.com/MyCATApach...

​ 至關於代理

在這裏插入圖片描述

做用

  • 攔截sql
  • 分片
  • 路由
  • 緩存
  • 讀寫分離

查詢若是是分片鍵那麼直接落到對應數據庫,若是不是分片鍵,那麼會路由到全部數據庫

haproxy負載均衡

keepalive 高可用

配置文件

rlue.xml

​ 分片數據庫

在這裏插入圖片描述
image-20190508120117289

對應的rule分片策略

範圍分片

在這裏插入圖片描述
這是範圍分片,0-200M表示到分片5

schema.xml

​ 邏輯數據庫邏輯表

server.xml

​ 配置當前服務

使用

單庫大表拆分

在這裏插入圖片描述

跨庫分表

在這裏插入圖片描述

讀寫分離

img

高可用

在這裏插入圖片描述

分庫分表雙主(數據雙向同步)策略

在這裏插入圖片描述

  • 須要經過haProxy作一個集羣
  • 再對haproxy作一個高可用

數據庫分庫分表

在互聯網行業中,最大的特色是併發量高、數據量大;爲了應對這兩個特色,後端的技術架構須要使用各類技術來支撐;而這個專題所講的是關於數據庫層面的優化
當數據庫的訪問量到達必定的瓶頸的時候,當數據庫單表數據比較大嚴重影響ddl性能的時候。咱們應該根據什麼思路去作優化和調整
  • 持久化存儲在大型分佈式架構下部分須要應對的問題
  • 如何去作分庫分表
  • 拆分策略
  • 分庫分錶帶來的問題及解決方案
  • 如何知道當前的系統須要作分庫分表
  • Mysql的讀寫分離實戰
  • Mysql主主複製以及基於keepalived實現雙主高可用
  • 基於HAProxy實現
  • 主從同步延遲問題及解決方案
  • 認識Mycat及Mycat安裝
  • Mycat數據切分實戰
  • Mycat讀寫分離實戰
  • Mycat分片策略
  • Mycat全局表配置

centos7安裝mysql5.7操做步驟

下載mysql的repo源

wget http://repo.mysql.com/mysql57-community-release-el7-8.noarch.rpm

安裝源

rpm -ivh mysql57-community-release-el7-8.noarch.rpm

安裝數據庫

yum install mysql-server

啓動數據庫

systemctl start mysqld

登陸到mysql

  1. 5.7版本默認對於root賬號有一個隨機密碼,能夠經過 grep "password" /var/log/mysqld.log得到,root@localhost: 此處爲隨機密碼
  2. 運行mysql -uroot -p 回車
  3. 粘貼隨機密碼
  4. 修改密碼
  5. 重啓

Open & Edit /etc/my.cnf or /etc/mysql/my.cnf, depending on your distro.
Add skip-grant-tables under [mysqld]
Restart Mysql

service mysqld restart

You should be able to login to mysql now using the below command mysql -u root -p
Run mysql> flush privileges;
Set new password by ALTER USER 'root'@'localhost' IDENTIFIED BY 'root';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';
Go back to /etc/my.cnf and remove/comment skip-grant-tables
Restart Mysql

service mysqld restart

Now you will be able to login with the new password mysql -u root -p

操做

  1. 默認的隨機密碼是沒辦法直接對數據庫作操做的,須要修改密碼,而後,5.7版本用了validate_password密碼增強插件,所以在修改密碼的時候絕對不是 123456 能糊弄過去的。須要嚴格按照規範去設置密碼
  2. 可是,若是想讓密碼簡單點也能夠,下降安全策略, 登陸到mysql客戶端執行以下兩條命令
set global validate_password_length=1;

set global validate_password_policy=0;
  1. 這樣就能設置簡單的密碼了,可是密碼長度必須是大於等於4位

賦權操做

默認狀況下其餘服務器的客戶端不能直接訪問mysql服務端,須要對ip受權
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
FLUSH PRIVILEGES;
相關文章
相關標籤/搜索