分庫分表
- 為什么要分庫分表?
- 超大容量問題
- 性能問題
- 如何去做到
- 垂直切分
①垂直分庫; 解決的是表過多的問題
②垂直分表; 解決單表列過多的問題 - 水平切分
大數據表拆成小表
- 常見的拆分策略
- 垂直切分
分片技術 - 水平切分
①一致性hash
②范圍切分 可以按照ID
③日期拆分
- 拆分以后帶來的問題
- 跨庫join的問題
①設計的時候考慮到應用層的join問題。
②在服務層去做調用;
A服務里查詢到一個list
bservice.select(list);
③全局表
數據變更比較少的基于全局應用的表
④做字段冗余(空間換時間的做法)
訂單表。 商家id 商家名稱
商家名稱變更- 定時任務、任務通知 - 唯一主鍵問題
①用自增id做主鍵
②UUID 性能比較低
③snowflake
④mongoDB
⑤zookeeper
⑥數據庫表 - 分布式事務問題
多個數據庫表之間保證原子性 性能問題; 互聯網公司用強一致性分布式事務比較少
Mysql的主從
- 數據庫的版本5.7版本
- 安裝以后文件對應的目錄
mysql的數據文件和二進制文件: /var/lib/mysql/
mysql的配置文件: /etc/my.cnf
mysql的日志文件: /var/log/mysql.log - 152 為master
①創建一個用戶’repl’,并且允許其他服務器可以通過該用戶遠程訪問master,通過該用戶去讀取二進制數據,實現數據同步
Create user repl identified by ‘repl
; repl用戶必須具有REPLICATION SLAVE權限,除此之外其他權限都不需要
GRANT REPLICATION SLAVE ON *.* TO ‘repl’@’%’ IDENTIFIED BY ‘repl’
;
②修改140 my.cnf配置文件,在[mysqld] 下添加如下配置
log-bin=mysql-bin
//啟用二進制日志文件
server-id=130
//服務器唯一ID
③重啟數據庫 systemctl restart mysqld
④登錄到數據庫,通過show master status 查看master的狀態信息 - 153 為slave
①修改142 my.cnf配置文件, 在[mysqld]下增加如下配置
server-id=132
//服務器id,唯一
relay-log=slave-relay-bin
relay-log-index=slave-relay-bin.index
read_only=1
②重啟數據庫:systemctl restart mysqld
③連接到數據庫客戶端,通過如下命令建立同步連接
change master to master_host=’192.168.100.152’
,master_port=3306,master_user=’repl’,master_password=’repl’,master_log_file=’mysql-bin.000001’,master_log_pos=0
;
master_log_file
和master_log_pos
從master的show master status可以找到對應的值,不能隨便寫。
④執行 start slave
⑤show slave status\G;查看slave服務器狀態,當如下兩個線程狀態為yes,表示主從復制配置成功
Slave_IO_Running=Yes
Slave_SQL_Running=Yes
主從同步的原理
①master記錄二進制日志。在每個事務更新數據完成之前,master在二日志記錄這些改變。MySQL將事務串行的寫入二進制日志,即使事務中的語句都是交叉執行的。在事件寫入二進制日志完成后,master通知存儲引擎提交事務
②slave將master的binary log拷貝到它自己的中繼日志。首先,slave開始一個工作線程——I/O線程。I/O線程在master上打開一個普通的連接,然后開始binlog dump process。Binlog dump process從master的二進制日志中讀取事件,如果已經跟上master,它會睡眠并等待master產生新的事件。I/O線程將這些事件寫入中繼日志
③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的內容 - binlog的格式
①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’ - 主從同步的延時問題
①當master庫tps比較高的時候,產生的DDL數量超過slave一個sql線程所能承受的范圍,或者slave的大型query語句產生鎖等待
②網絡傳輸: bin文件的傳輸延遲
③磁盤的讀寫耗時:文件通知更新、磁盤讀取延遲、磁盤寫入延遲 - 解決方案
①在數據庫和應用層增加緩存處理,優先從緩存中讀取數據
②減少slave同步延遲,可以修改slave庫sync_binlog屬性;
sync_binlog=0
文件系統來調度把binlog_cache刷新到磁盤
sync_binlog=n
③增加延時監控
Nagios做網絡監控
mk-heartbeat