分佈式系列十四: 分庫分表

分庫分表是爲了應對業務系統在高併發,大數據量背景下而對數據存儲進行的優化.html

關於分表, 本人使用過SQLSERVER數據庫有分區表, 表分區比起人爲按必定策略分表有必定優點, 並且生產環境中表分區也一直運行良好. sqlserver2000有分區視圖的概念, 而分區視圖實際就是創建在分表基礎上的, 爲遵循分表策略的一系列表提供了一個統一的入口.mysql

使用表分區或分表方案各有利弊, 具體還需視狀況作權衡.ios

爲何要分庫分表

  • 提升查詢性能
  • 容量提高

分庫分表的方法

  • 垂直切分redis

    1. 垂直分庫: 按照業務領域拆分, 每一個庫都存儲了該業務領域內的數據. 這解決了表過多的問題
    2. 垂直分表: 解決了表中列過多的問題. 避免表過寬致使的查詢性能問題.
  • 水平切分算法

    防止表的數據量過大, 拆分的表結構徹底相同, 也就是將數據分佈到不一樣的表中, 能夠是同一個庫, 也能夠是不一樣庫.sql

拆分策略

  • 垂直拆分: ER(Entity Relationship)分片, 須要注意相關的表拆分到同一個庫, 防止join問題.數據庫

  • 水平拆分服務器

    1. 一致性hash(注意節點變化致使的問題)
    2. 範圍 通常按自增id
    3. 日期

拆分帶來的問題

  1. 跨庫join;網絡

    解決方案: 設計前儘可能考慮; 服務層調用; 使用全局表; 字段冗餘;併發

  2. 跨表排序

  3. 惟一主鍵

    自增id致使的重複.
    UUID: 性能較低
    snowflake: 雪花算法
    zookeeper,redis,mongoDB
    數據庫表

  4. 分佈式事務

    互聯網不多使用強一致性分佈式事務, 但使用時就必須考慮.

分庫分表的難度在於業務

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

  • 提早規劃 (主鍵, join問題提早解決)
  • 單表數據超過1000w, 且還在增加

表分區的缺點

  • 分區字段不靈活, 可能致使表鎖
  • 關聯查詢的性能可能不高
  • 本身分庫分表有更大靈活性, 表分區將查詢執行計劃交給mysql, 對開發人員透明, 可能很差優化.

MySql 主從

可參看這篇文章

針對寫少讀多的狀況. 能夠配置多個只讀從庫, 使用HaProxy作負載均衡.

安裝MySql

apt-get install mysql-server 安裝最新版本的mysql
service mysql start 服務方式啓動 或者轉到目錄/usr/bin使用 ./mysqld_safe &啓動
service mysql stop 關閉, 或者使用mysqladmin -u root shutdown

GRANT ALL PRIVILEAGES ON *.* TO 'root'@'%' INDENTIFIED BY 'root' WITH GRANT OPTION 受權外網訪問

主從配置

從節點建立用戶 create user repl identified by 'repl'
從節點受權 grant replication slave on *.* to 'repl'@'%' identified by 'repl'

mysql的數據文件和二進制文件: /var/lib/mysql/
mysql配置文件: /etc/mysql/my.cnf
mysql的日誌文件: /var/log/mysql/mysql.log

配置文件中my.cnf中:

主配置:

log-bin=mysql-bin  //開啓日誌文件
server.id=123  //惟一id

show master status; 能夠查看文件名稱

從配置:

server.id=124
relay-log=slave-relay-bin  //打開中繼日誌
relay-log-index=slave-relay-bin.index
read-only=1 //只讀

從節點指定主服務器節點:

change master to master_host='192.168.11.123',master_port=3306,master_user='repl',master_password='repl',master_log_file='mysql.bin.000001',master_log_pos=154;

master_log_file='mysql.bin.000001',master_log_pos=154;就是使用show master status;查詢到的信息.

從節點啓動slave: start slave;
從節點查看狀態: show slave status;

主從同步原理

Slave 中有兩個線程, IO和SQL, 分別用來同步日誌文件和執行sql.

master -> 寫binlog -> slave IO/Thread -> replylog -> SQL/Thread -> slave DB

mysqlbinlog --base64-output=decode-rows -v mysql-bin.00001 用來查看binlog日誌文件內容

日誌文件的存儲與kafka的日誌優勢相似, 順序存儲, 分文件存儲.

binlog文件的格式:

  • statement 基於sql語句, 如update A set name=name+'-'; effect row 1000
  • row 基於行模式, 存在1000條數據變動, 記錄變化的值 默認爲row
  • mixed 混合模式, mysql自行處理.

show binlog events in 'mysql-bin.00001' 查看日誌文件的事件
show variablees like '%log%' //查看日誌模式 statement row mixed
set global binlog_format='minxed' //設置模式 或者在配置文件中指定binlog_format=minxed

雙主

均可以寫數據, 可能存在數據不一致.

主從同步的問題

  • 數據同步延時, 大量數據同步, 網絡問題, IO阻塞
  • 延時監控: Nagios, mk-heartbeat redis能夠提供應用層解決方案
相關文章
相關標籤/搜索