1. 程式人生 > >資料庫 分庫 分表 分割槽

資料庫 分庫 分表 分割槽

我們知道,如果我們使用mysql,當資料庫資料量達到一定資料量之後,會考慮對資料庫進行分庫分表等操作,但是在什麼情況下做怎麼的切分,下面分表介紹。

一、分庫

1 分庫原因

首先,在單臺數據庫伺服器效能足夠的情況下,分庫對於資料庫效能是沒有影響的。在資料庫儲存上,database只起到一個namespace的作用。database中的表文件儲存在一個以database名命名的資料夾中。比如下面的employees資料庫:

mysql> show tables in employees;
+---------------------+
| Tables_in_employees |
+---------------------+
| departments         |
| dept_emp            |
| dept_manager        |
| employees           |
| salaries            |
| titles              |
+---------------------+

在作業系統中看是這樣的:

# haitian at haitian-coder.local in /usr/local/var/mysql/employees on git:master ● [21:19:47]
→ ls  
db.opt           dept_emp.frm     dept_manager.ibd salaries.frm     titles.ibd
departments.frm  dept_emp.ibd     employees.frm    salaries.ibd
departments.ibd  dept_manager.frm employees.ibd    titles.frm

database不是檔案,只起到namespace的作用,所以MySQLdatabase大小當然也是沒有限制的,而且對裡面的表數量也沒有限制。

所以,為什麼要分庫呢?

答案是為了解決單臺伺服器的效能問題,當單臺數據庫伺服器無法支撐當前的資料量時,就需要根據業務邏輯緊密程度把表分成幾撮,分別放在不同的資料庫伺服器中以降低單臺伺服器的負載。

分庫一般考慮的是垂直切分,除非在垂直切分後,資料量仍然多到單臺伺服器無法負載,才繼續水平切分。

比如一個論壇系統的資料庫因當前伺服器效能無法滿足需要進行分庫。先垂直切分,按業務邏輯把使用者相關資料表比如使用者資訊、積分、使用者間私信等放入user資料庫;論壇相關資料表比如板塊,帖子,回覆等放入forum資料庫,兩個資料庫放在不同伺服器上。

拆分後表往往不可能完全無關聯,比如帖子中的發帖人、回覆人這些資訊都在user資料庫中。未拆分前可能一次聯表查詢就能獲取當前帖子的回覆、發帖人、回覆人等所有資訊,拆分後因為跨資料庫無法聯表查詢,只能多次查詢獲得最終資料。

所以總結起來,分庫的目的是降低單臺伺服器負載,切分原則是根據業務緊密程度拆分,缺點是跨資料庫無法聯表查詢。

二、分表

1 分表的原因

當資料量超大的時候,B-Tree索引就無法起作用了。除非是索引覆蓋查詢,否則資料庫伺服器需要根據索引掃描的結果回表,查詢所有符合條件的記錄,如果資料量巨大,這將產生大量隨機I/O,隨之,資料庫的響應時間將大到不可接受的程度。另外,索引維護(磁碟空間、I/O操作)的代價也非常高。

2 垂直分表

原因:

1.根據MySQL索引實現原理及相關優化策略的內容我們知道Innodb主索引葉子節點儲存著當前行的所有資訊,所以減少欄位可使記憶體載入更多行資料,有利於查詢。

2.受限於作業系統中的檔案大小限制。

切分原則: 把不常用或業務邏輯不緊密或儲存內容比較多的欄位分到新的表中可使表儲存更多資料。。

3 水平分表

原因:

1.隨著資料量的增大,table行數巨大,查詢的效率越來越低。

2.同樣受限於作業系統中的檔案大小限制,資料量不能無限增加,當到達一定容量時,需要水平切分以降低單表(檔案)的大小。

切分原則: 增量區間或雜湊或其他業務邏輯。

使用哪種切分方法要根據實際業務邏輯判斷。

比如對錶的訪問多是近期產生的新資料,歷史資料訪問較少,可以考慮根據時間增量把資料按照一定時間段(比如每年)切分。

如果對錶的訪問較均勻,沒有明顯的熱點區域,則可以考慮用範圍(比如每500w一個表)或普通Hash或一致性Hash來切分。

全域性主鍵問題:

原本依賴資料庫生成主鍵(比如自增)的表在拆分後需要自己實現主鍵的生成,因為一般拆分規則是建立在主鍵上的,所以在插入新資料時需要確定主鍵後才能找到儲存的表。

實際應用中也已經有了比較成熟的方案。比如對於自增列做主鍵的表,flickr的全域性主鍵生成方案很好的解決了效能和單點問題,具體實現原理可以參考這個帖子。除此之外,還有類似於uuid的全域性主鍵生成方案,比如達達參考的Instagram的ID生成器

一致性Hash:

使用一致性Hash切分比普通的Hash切分可擴充套件性更強,可以實現拆分表的新增和刪除。一致性Hash的具體原理可以參考這個帖子,如果拆分後的表儲存在不同伺服器節點上,可以跟帖子一樣對節點名或ip取Hash;如果拆分後的表存在一個伺服器中則可對拆分後的表名取Hash。

三、MySQL的分割槽表

上面介紹的傳統的分庫分表都是在應用層實現,拆分後都要對原有系統進行很大的調整以適應新拆分後的庫或表,比如實現一個SQL中介軟體、原本的聯表查詢改成兩次查詢、實現一個全域性主鍵生成器等等。

而下面介紹的MySQL分割槽表是在資料庫層面,MySQL自己實現的分表功能,在很大程度上簡化了分表的難度。

1 介紹

對使用者來說,分割槽表是一個獨立的邏輯表,但是底層由多個物理子表實現。

也就是說,對於原表分割槽後,對於應用層來說可以不做變化,我們無需改變原有的SQL語句,相當於MySQL幫我們實現了傳統分表後的SQL中介軟體,當然,MySQL的分割槽表的實現要複雜很多。

另外,在建立分割槽時可以指定分割槽的索引檔案和資料檔案的儲存位置,所以可以把資料表的資料分佈在不同的物理裝置上,從而高效地利用多個硬體裝置。

一些限制:

1.在5.6.7之前的版本,一個表最多有1024個分割槽;從5.6.7開始,一個表最多可以有8192個分割槽。

2.分割槽表中無法使用外來鍵約束。

3.主表的所有唯一索引列(包括主鍵)都必須包含分割槽欄位。MySQL官方文件中寫的是:

All columns used in the partitioning expression for a partitioned table must be part of every unique key that the table may have.

這句話不是很好理解,需要通過例子才能明白,MySQL官方文件也為此限制特意做了舉例和解釋

2 分割槽表型別

RANGE分割槽

根據範圍分割槽,範圍應該連續但是不重疊,使用PARTITION BY RANGEVALUES LESS THAN關鍵字。不使用COLUMNS關鍵字時RANGE括號內必須為整數字段名或返回確定整數的函式。

根據數值範圍:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT NOT NULL,
    store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6),
    PARTITION p1 VALUES LESS THAN (11),
    PARTITION p2 VALUES LESS THAN (16),
    PARTITION p3 VALUES LESS THAN MAXVALUE
);

根據TIMESTAMP範圍:

CREATE TABLE quarterly_report_status (
    report_id INT NOT NULL,
    report_status VARCHAR(20) NOT NULL,
    report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) (
    PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ),
    PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ),
    PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ),
    PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ),
    PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ),
    PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ),
    PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ),
    PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ),
    PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ),
    PARTITION p9 VALUES LESS THAN (MAXVALUE)
);

新增COLUMNS關鍵字可定義非integer範圍及多列範圍,不過需要注意COLUMNS括號內只能是列名,不支援函式;多列範圍時,多列範圍必須呈遞增趨勢:

根據DATEDATETIME範圍:

CREATE TABLE members (
    firstname VARCHAR(25) NOT NULL,
    lastname VARCHAR(25) NOT NULL,
    username VARCHAR(16) NOT NULL,
    email VARCHAR(35),
    joined DATE NOT NULL
)
PARTITION BY RANGE COLUMNS(joined) (
    PARTITION p0 VALUES LESS THAN ('1960-01-01'),
    PARTITION p1 VALUES LESS THAN ('1970-01-01'),
    PARTITION p2 VALUES LESS THAN ('1980-01-01'),
    PARTITION p3 VALUES LESS THAN ('1990-01-01'),
    PARTITION p4 VALUES LESS THAN MAXVALUE
);

根據多列範圍:

CREATE TABLE rc3 (
    a INT,
    b INT
)
PARTITION BY RANGE COLUMNS(a,b) (
    PARTITION p0 VALUES LESS THAN (0,10),
    PARTITION p1 VALUES LESS THAN (10,20),
    PARTITION p2 VALUES LESS THAN (10,30),
    PARTITION p3 VALUES LESS THAN (10,35),
    PARTITION p4 VALUES LESS THAN (20,40),
    PARTITION p5 VALUES LESS THAN (MAXVALUE,MAXVALUE)
 );

List分割槽

根據具體數值分割槽,每個分割槽數值不重疊,使用PARTITION BY LISTVALUES IN關鍵字。跟Range分割槽類似,不使用COLUMNS關鍵字時List括號內必須為整數字段名或返回確定整數的函式。

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LIST(store_id) (
    PARTITION pNorth VALUES IN (3,5,6,9,17),
    PARTITION pEast VALUES IN (1,2,10,11,19,20),
    PARTITION pWest VALUES IN (4,12,13,14,18),
    PARTITION pCentral VALUES IN (7,8,15,16)
);

數值必須被所有分割槽覆蓋,否則插入一個不屬於任何一個分割槽的數值會報錯。

mysql> CREATE TABLE h2 (
    ->   c1 INT,
    ->   c2 INT
    -> )
    -> PARTITION BY LIST(c1) (
    ->   PARTITION p0 VALUES IN (1, 4, 7),
    ->   PARTITION p1 VALUES IN (2, 5, 8)
    -> );
Query OK, 0 rows affected (0.11 sec)

mysql> INSERT INTO h2 VALUES (3, 5);
ERROR 1525 (HY000): Table has no partition for value 3

當插入多條資料出錯時,如果表的引擎支援事務(Innodb),則不會插入任何資料;如果不支援事務,則出錯前的資料會插入,後面的不會執行。

可以使用IGNORE關鍵字忽略出錯的資料,這樣其他符合條件的資料會全部插入不受影響。

mysql> TRUNCATE h2;
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM h2;
Empty set (0.00 sec)

mysql> INSERT IGNORE INTO h2 VALUES (2, 5), (6, 10), (7, 5), (3, 1), (1, 9);
Query OK, 3 rows affected (0.00 sec)
Records: 5  Duplicates: 2  Warnings: 0

mysql> SELECT * FROM h2;
+------+------+
| c1   | c2   |
+------+------+
|    7 |    5 |
|    1 |    9 |
|    2 |    5 |
+------+------+
3 rows in set (0.00 sec)

Range分割槽相同,新增COLUMNS關鍵字可支援非整數和多列。

Hash分割槽

Hash分割槽主要用來確保資料在預先確定數目的分割槽中平均分佈,Hash括號內只能是整數列或返回確定整數的函式,實際上就是使用返回的整數對分割槽數取模。

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4;
CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH( YEAR(hired) )
PARTITIONS 4;

Hash分割槽也存在與傳統Hash分表一樣的問題,可擴充套件性差。MySQL也提供了一個類似於一致Hash的分割槽方法-線性Hash分割槽,只需要在定義分割槽時新增LINEAR關鍵字,如果對實現原理感興趣,可以檢視官方文件

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LINEAR HASH( YEAR(hired) )
PARTITIONS 4;

Key分割槽

按照KEY進行分割槽類似於按照HASH分割槽,除了HASH分割槽使用的使用者定義的表示式,而KEY分割槽的 雜湊函式是由MySQL 伺服器提供。MySQL 簇(Cluster)使用函式MD5()來實現KEY分割槽;對於使用其他儲存引擎的表,伺服器使用其自己內部的 雜湊函式,這些函式是基於與PASSWORD()一樣的運演算法則。

Key分割槽與Hash分割槽很相似,只是Hash函式不同,定義時把Hash關鍵字替換成Key即可,同樣Key分割槽也有對應與線性Hash的線性Key分割槽方法。

CREATE TABLE tk (
    col1 INT NOT NULL,
    col2 CHAR(5),
    col3 DATE
)
PARTITION BY LINEAR KEY (col1)
PARTITIONS 3;

另外,當表存在主鍵或唯一索引時可省略Key括號內的列名,Mysql將按照主鍵-唯一索引的順序選擇,當找不到唯一索引時報錯。

子分割槽

子分割槽是分割槽表中每個分割槽的再次分割。建立子分割槽方法:

CREATE TABLE ts (id INT, purchased DATE)
    PARTITION BY RANGE( YEAR(purchased) )
    SUBPARTITION BY HASH( TO_DAYS(purchased) )
    SUBPARTITIONS 2 (
        PARTITION p0 VALUES LESS THAN (1990),
        PARTITION p1 VALUES LESS THAN (2000),
        PARTITION p2 VALUES LESS THAN MAXVALUE
    );

CREATE TABLE ts (id INT, purchased DATE)
    PARTITION BY RANGE( YEAR(purchased) )
    SUBPARTITION BY HASH( TO_DAYS(purchased) ) (
        PARTITION p0 VALUES LESS THAN (1990) (
            SUBPARTITION s0
                DATA DIRECTORY = '/disk0/data'
                INDEX DIRECTORY = '/disk0/idx',
            SUBPARTITION s1
                DATA DIRECTORY = '/disk1/data'
                INDEX DIRECTORY = '/disk1/idx'
        ),
        PARTITION p1 VALUES LESS THAN (2000) (
            SUBPARTITION s2
                DATA DIRECTORY = '/disk2/data'
                INDEX DIRECTORY = '/disk2/idx',
            SUBPARTITION s3
                DATA DIRECTORY = '/disk3/data'
                INDEX DIRECTORY = '/disk3/idx'
        ),
        PARTITION p2 VALUES LESS THAN MAXVALUE (
            SUBPARTITION s4
                DATA DIRECTORY = '/disk4/data'
                INDEX DIRECTORY = '/disk4/idx',
            SUBPARTITION s5
                DATA DIRECTORY = '/disk5/data'
                INDEX DIRECTORY = '/disk5/idx'
        )
    );

需要注意的是:每個分割槽的子分割槽數必須相同。如果在一個分割槽表上的任何分割槽上使用SUBPARTITION來明確定義任何子分割槽,那麼就必須定義所有的子分割槽,且必須指定一個全表唯一的名字。

分割槽表的使用及查詢優化

根據實際情況選擇分割槽方法

對現有表分割槽的原則與傳統分表一樣。

傳統的按照增量區間分表對應於分割槽的Range分割槽,比如對錶的訪問多是近期產生的新資料,歷史資料訪問較少,則可以按一定時間段(比如年或月)或一定數量(比如100萬)對錶分割槽,具體根據哪種取決於表索引結構。分割槽後最後一個分割槽即為近期產生的資料,當一段時間過後資料量再次變大,可對最後一個分割槽重新分割槽(REORGANIZE PARTITION)把一段時間(一年或一月)或一定數量(比如100萬)的資料分離出去。

傳統的雜湊方法分表對應於分割槽的Hash/Key分割槽,具體方法上面已經介紹過。

查詢優化

分割槽的目的是為了提高查詢效率,如果查詢範圍是所有分割槽那麼就說明分割槽沒有起到作用,我們用explain partitions命令來檢視SQL對於分割槽的使用情況。

一般來說,就是在where條件中加入分割槽列。

比如表salaries結構為:

mysql> show create table salaries\G;
*************************** 1. row ***************************
       Table: salaries
Create Table: CREATE TABLE `salaries` (
  `emp_no` int(11) NOT NULL,
  `salary` int(11) NOT NULL,
  `from_date` date NOT NULL,
  `to_date` date NOT NULL,
  PRIMARY KEY (`emp_no`,`from_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (year(from_date))
(PARTITION p1 VALUES LESS THAN (1985) ENGINE = InnoDB,
 PARTITION p2 VALUES LESS THAN (1986) ENGINE = InnoDB,
 PARTITION p3 VALUES LESS THAN (1987) ENGINE = InnoDB,
 PARTITION p4 VALUES LESS THAN (1988) ENGINE = InnoDB,
 PARTITION p5 VALUES LESS THAN (1989) ENGINE = InnoDB,
 PARTITION p6 VALUES LESS THAN (1990) ENGINE = InnoDB,
 PARTITION p7 VALUES LESS THAN (1991) ENGINE = InnoDB,
 PARTITION p8 VALUES LESS THAN (1992) ENGINE = InnoDB,
 PARTITION p9 VALUES LESS THAN (1993) ENGINE = InnoDB,
 PARTITION p10 VALUES LESS THAN (1994) ENGINE = InnoDB,
 PARTITION p11 VALUES LESS THAN (1995) ENGINE = InnoDB,
 PARTITION p12 VALUES LESS THAN (1996) ENGINE = InnoDB,
 PARTITION p13 VALUES LESS THAN (1997) ENGINE = InnoDB,
 PARTITION p14 VALUES LESS THAN (1998) ENGINE = InnoDB,
 PARTITION p15 VALUES LESS THAN (1999) ENGINE = InnoDB,
 PARTITION p16 VALUES LESS THAN (2000) ENGINE = InnoDB,
 PARTITION p17 VALUES LESS THAN (2001) ENGINE = InnoDB,
 PARTITION p18 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */

則下面的查詢沒有利用分割槽,因為partitions中包含了所有的分割槽:

mysql> explain partitions select * from salaries where salary > 100000\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: salaries
   partitions: p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 2835486
        Extra: Using where

只有在where條件中加入分割槽列才能起到作用,過濾掉不需要的分割槽:

mysql> explain partitions select * from salaries where salary > 100000 and from_date > '1998-01-01'\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: salaries
   partitions: p15,p16,p17,p18
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1152556
        Extra: Using where

與普通搜尋一樣,在運算子左側使用函式將使分割槽過濾失效,即使與分割槽函式想同也一樣:

mysql> explain partitions select * from salaries where salary > 100000 and year(from_date) > 1998\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: salaries
   partitions: p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 2835486
        Extra: Using where

四、分割槽和分表的比較

  • 傳統分表後,countsum等統計操作只能對所有切分表進行操作後之後在應用層再次計算得出最後統計資料。而分割槽表則不受影響,可直接統計。

Queries involving aggregate functions such as SUM() and COUNT() can easily be parallelized. A simple example of such a query might be SELECT salesperson_id, COUNT(orders) as order_total FROM sales GROUP BY salesperson_id;. By “parallelized,” we mean that the query can be run simultaneously on each partition, and the final result obtained merely by summing the results obtained for all partitions.

  • 分割槽對原系統改動最小,分割槽只涉及資料庫層面,應用層不需要做出改動。

  • 分割槽有個限制是主表的所有唯一欄位(包括主鍵)必須包含分割槽欄位,而分表沒有這個限制。

  • 分表包括垂直切分和水平切分,而分割槽只能起到水平切分的作用。

五、常用分庫分表

1 tddl介紹

tddl主要分為三次,matrix、group、atom層;

matrix層

Sql解析->規則引擎計算->資料執行->合併結果

group層

讀寫分離、權重、寫的HA切換、讀的HA切換、slave節點

atom層

1 單個數據庫的抽象

2 jboss資料來源, ip port 使用者名稱密碼都可 以動態修改

3 Thread count模式,保護 業務的處理執行緒,超過指定值,保護啟動。

4 動態阻止某個SQL執行

5 執行次數統計和限制

tddl 唯一鍵生成方式

目前基於tddl進行分庫分表後,原本一個數據庫上的自增id的結果,在分庫分表下並不是全域性唯一的. 所以,分庫分表後需要有一種技術可以生成全域性的唯一id.

唯一鍵的生成方式必須具備:1)全域性唯一;2)高可用;3)高效能;

tddl主要使用資料庫+記憶體的方式實現,在記憶體中進行分配 優勢:簡單高效 缺點:無法保證自增順序如下,下面內步長1000:

group value
group_0 0
group_1 1000
group_2 2000
group_3 3000

當需要產生唯一鍵時,從上面4個group中隨機選擇一個,獲取value+步長的id,例如,從group_1獲取1000~1000+1000的id,批量獲取,提高效能。獲取之後,資料庫的記錄變為下面的格式:

group value
group_0 0
group_1 5000
group_2 2000
group_3 3000

每次獲取之後,將對應group的值變為,value+group的個數*步長。

相關推薦

資料庫 分庫 分割槽

我們知道,如果我們使用mysql,當資料庫資料量達到一定資料量之後,會考慮對資料庫進行分庫分表等操作,但是在什麼情況下做怎麼的切分,下面分表介紹。 一、分庫 1 分庫原因 首先,在單臺數據庫伺服器效能足夠的情況下,分庫對於資料庫效能是沒有影響的。在資料庫儲存上,database只起到一個namespace的作

資料庫分庫(sharding)系列(五) 一種支援自由規劃無須資料遷移和修改路由程式碼的Sharding擴容方案(轉)...

作為一種資料儲存層面上的水平伸縮解決方案,資料庫Sharding技術由來已久,很多海量資料系統在其發展演進的歷程中都曾經歷過分庫分表的Sharding改造階段。簡單地說,Sharding就是將原來單一資料庫按照一定的規則進行切分,把資料分散到多臺物理機(我們稱之為Shard)上儲存,從

阿里P8架構師談:資料庫分庫、讀寫分離的原理實現,使用場景

為什麼要分庫分表和讀寫分離?   類似淘寶網這樣的網站,海量資料的儲存和訪問成為了系統設計的瓶頸問題,日益增長的業務資料,無疑對資料庫造成了相當大的負載,同時對於系統的穩定性和擴充套件性提出很高的要求。隨著時間和業務的發展,資料庫中的表會越來越多,表中的資料量也會越來越大,相應地,

資料庫分庫 sharding 系列 四 多資料來源的事務處理

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

資料庫分庫 sharding 系列 五 一種支援自由規劃無須資料遷移和修改路由程式碼的Sharding擴容方案

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

資料庫分庫存在的問題及解決方案

讀寫分離分散了資料庫讀寫操作的壓力,但是沒有分散儲存壓力,當資料庫的資料量達到千萬甚至上億條的時候,單臺數據庫伺服器的儲存能力就會達到瓶頸,主要體現在以下幾個方面: 資料量太大,讀寫效能會下降,即使有索引,索引也會變得很大,效能同樣會下降 資料檔案會變得很大,資料庫備份和恢復需要消耗更長的時間

資料庫分庫分表(sharding)系列(三) 關於使用框架還是自主開發以及sharding實現層面的考量 資料庫分庫分表(sharding)系列(二) 全域性主鍵生成策略 資料庫分庫分表(sharding)系列(一) 拆分實施策略和示例演示

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

資料庫分庫——擴容無須資料遷移的分片演算法

擴容無須資料遷移的分片演算法 常見的分庫分表方案大都用主鍵mod一個數(如分為8個庫,則 id % 8 根據餘數決定落到哪個分片)。此種方案中,如果要拓展資料庫將是十分複雜的事情(例如拓展為10個,則程式碼需要改為 id % 10 之前的舊資料也要做遷移)。我們希望有一種支援自由規劃無須資料遷移和修

資料庫分庫思路及案例分析

一. 資料切分 關係型資料庫本身比較容易成為系統瓶頸,單機儲存容量、連線數、處理能力都有限。當單表的資料量達到 1000W 或 100G 以後,由於查詢維度較多,即使新增從庫、優化索引,做很多操作時效能仍下降嚴重。此時就要考慮對其進行切分了,切分的目的就在於減少資料庫的負擔,縮短查詢時間

資料庫分庫(持續更新中)

今天學習了資料庫分表分庫,感覺記錄下一些東西以便以後的檢視。 1、資料庫建立索引,可以加快表資料的查詢,但是過多的索引,會佔用大量的記憶體,維護難度較大,因為索引底層的演算法是B-tree,樹的特點就是查詢資料快按時資料增刪改比較慢。 2、資料庫的表拆分,分為水平拆分,垂直拆分,水平垂直拆分(自定義的)。

資料庫分庫、讀寫分離的實現原理及使用場景

為什麼要分庫分表和讀寫分離? 類似淘寶網這樣的網站,海量資料的儲存和訪問成為了系統設計的瓶頸問題,日益增長的業務資料,無疑對資料庫造成了相當大的負載,同時對於系統的穩定性和擴充套件性提出很高的要求。隨著時間和業務的發展,資料庫中的表會越來越多,表中的資料量也會越來越

day81_淘淘商城專案_14_專案釋出 + Linux下安裝mysql + tomcat熱部署 + 資料庫分庫 + Mycat學習_匠心筆記

第十四天: 1、Linux上mysql的安裝 2、系統的部署 3、mycat的介紹 4、專案總結 5、面試中的問題 1、開發流程淺解 2、專案釋出前的準備 1、測試  a) 本地單元測試  b) 測試環境測試(1,2,3,4,5)  c) 使用

分庫分割槽,讀寫分離

一、分割槽的概念         資料分割槽是一種物理資料庫的設計技術,它的目的是為了在特定的SQL操作中減少資料讀寫的總量以縮減響應時間。         分割槽並不是生成新的資料表,而是將表的資料均衡分攤到不同的硬碟,系統或是不同伺服器儲存介子中,實際上還是一張表

mysql資料庫分庫

一、分庫分表前的問題 1、使用者請求量太大 因為單伺服器TPS,記憶體,IO都是有限的。 解決方法:分散請求到多個伺服器上; 其實使用者請求和執行一個sql查詢是本質是一樣的,都是請求一個資源,只是使用者請求還會經過閘道器,路由,http伺服器等。 2、單庫太大 單個

資料庫分庫的應用場景及解決方案

現實業務場景中,為了保障客戶體驗並滿足業務的線性增長。會對資料量巨大,且業務會始終進行的產品進行分表分庫策略。但是如何合理的根據業務採取爭取的分表分庫策略至關重要。下面以具體例項來進行分析。 場景一:使用者中心資料庫切分架構實踐|場景介紹     使用者中心是一個十分常見

資料庫分庫後,如何部署上線?

1. 引言 我們先來講一個段子 面試官:“有併發的經驗沒?” 應聘者:“有一點。” 面試官:“那你們為了處理併發,做了哪些優化?” 應聘者:“前後端分離啊,限流啊,分庫分表啊。。” 面試官:"談談分庫分表吧?" 應聘者:“bala。bala。bala

資料庫分庫 sharding 系列 三 關於使用框架還是自主開發以及sharding實現層面的考量

                當團隊對系統業務和資料庫進行了細緻的梳理,確定了切分方案後,接下來的問題就是如何去實現切分方案了,目前在sharding方面有不少的開源框架和產品可供參考,同時很多團隊也會選擇自主開發實現,而不管是選擇框架還是自主開發,都會面臨一個在哪一層上實現sharding邏輯的問題,本文

基於代理的資料庫分庫框架 Mycat實踐

文章共 1796字,閱讀大約需要 4分鐘 ! 概 述 在如今海量資料充斥的網際網路環境下,分庫分表的意義我想在此處就不用贅述了。而分庫分表目前流行的方案最起碼有兩種: 方案一:基於應用層的分片,即應用層程式碼直接完成分片邏輯 方案二:基於代理層的分片,即在應用程式碼和底層資料庫中

資料庫分庫中介軟體對比(很全)

分割槽:對業務透明,分割槽只不過把存放資料的檔案分成了許多小塊,例如mysql中的一張表對應三個檔案.MYD,MYI,frm。根據一定的規則把資料檔案(MYD)和索引檔案(MYI)進行了分割,分割槽後的表呢,還是一張表。分割槽可以把表分到不同的硬碟上,但不能分配到不同伺服器上。優點:資料不存在多個副本,不必進

資料庫分庫策略的具體實現方案

相關文章: 一、MySQL擴充套件具體的實現方式 隨著業務規模的不斷擴大,需要選擇合適的方案去應對資料規模的增長,以應對逐漸增長的訪問壓力和資料量。 關於資料庫的擴充套件主要包括:業務拆分、主從複製,資料庫分庫與分表。這篇文章主要講