《網(wǎng)易視頻云分享:Facebook memcache優(yōu)化經(jīng)驗(yàn)》要點(diǎn):
本文介紹了網(wǎng)易視頻云分享:Facebook memcache優(yōu)化經(jīng)驗(yàn),希望對(duì)您有用。如果有疑問(wèn),可以聯(lián)系我們。
相關(guān)主題:memcache擴(kuò)展 / 鍵值KeyValue存儲(chǔ)數(shù)據(jù)庫(kù)
網(wǎng)易視頻云是網(wǎng)易傾力打造的一款基于云計(jì)算的分布式多媒體處理集群和專(zhuān)業(yè)音視頻技術(shù),提供穩(wěn)定流暢、低時(shí)延、高并發(fā)的視頻直播、錄制、存儲(chǔ)、轉(zhuǎn)碼及點(diǎn)播等音視頻的PAAS服務(wù),在線(xiàn)教育、長(zhǎng)途醫(yī)療、娛樂(lè)秀場(chǎng)、在線(xiàn)金融等各行業(yè)及企業(yè)用戶(hù)只需經(jīng)過(guò)簡(jiǎn)單的開(kāi)發(fā)即可打造在線(xiàn)音視頻平臺(tái).現(xiàn)在,網(wǎng)易視頻云的技術(shù)專(zhuān)家給大家分享一則技術(shù)文:Facebook memcache優(yōu)化經(jīng)驗(yàn).
memcache是facebook的重要基礎(chǔ)設(shè)施, 有數(shù)據(jù)為證: 緩存了T級(jí)記錄, 支持每秒G級(jí)別拜訪(fǎng)次數(shù), 單頁(yè)面經(jīng)常拜訪(fǎng)上千次memcache. facebook從memcache節(jié)點(diǎn)、集群、region、跨region等各層次對(duì)memcache做了大量?jī)?yōu)化和改造, 本文簡(jiǎn)單介紹facebook在memcache節(jié)點(diǎn)和集群層次做的一些優(yōu)化工作.
降低延遲的辦法:
并行哀求.根據(jù)數(shù)據(jù)依賴(lài)關(guān)系構(gòu)建DAG, 無(wú)依賴(lài)的數(shù)據(jù)批量發(fā)送到memache服務(wù)端, 根據(jù)統(tǒng)計(jì)平均每個(gè)哀求包括24個(gè)key.
通訊優(yōu)化.get操作使用UDP,刪除和更新操作使用TCP, 響應(yīng)時(shí)間降低20%.
流量控制.通過(guò)滑動(dòng)窗口控制單個(gè)客戶(hù)端發(fā)出的并發(fā)哀求數(shù)目,避免服務(wù)器過(guò)載.
降低負(fù)載的辦法:
Lease, 用于解決 memcache應(yīng)用過(guò)程常見(jiàn)的兩個(gè)問(wèn)題: (1)stale sets, 由于并發(fā)更新哀求發(fā)生亂序, 導(dǎo)致memcache中存儲(chǔ)了舊的數(shù)據(jù); (2)thundering herds(驚群), 讀寫(xiě)率特別高的鍵值, 寫(xiě)操作失效memcache時(shí),大量讀操作不命中,導(dǎo)致后端壓力激增. lease的原理是, memcache讀不命中時(shí),返回一個(gè)64位token給客戶(hù)端, 只有當(dāng)token有效時(shí), 才允許客戶(hù)端加載數(shù)據(jù)到memcache. 服務(wù)端接收到delete哀求時(shí)(寫(xiě)操作之前應(yīng)用一般會(huì)發(fā)送delete哀求去失效memcache),則失效鍵值對(duì)應(yīng)的所有token, 從而避免讀不命中的客戶(hù)端加載老數(shù)據(jù)到緩存. memcache服務(wù)器限制每個(gè)鍵值10s內(nèi)只產(chǎn)生一個(gè)token, token產(chǎn)生后10s內(nèi), 其他客戶(hù)端若讀不到鍵值,則等待一小段時(shí)間之后,再次重試. 由于新的value很快就加載到緩存中, 重試一次讀到最新value的概率非常大, 這就徹底避免了thundering herds問(wèn)題. 根據(jù)facebook的實(shí)測(cè)結(jié)果, 在某些場(chǎng)景下有l(wèi)ease能將數(shù)據(jù)庫(kù)的qps從17K降低到1.3K. 此外, 刪除鍵值時(shí),只在數(shù)據(jù)上做一個(gè)已刪除標(biāo)志,讓數(shù)據(jù)在緩存中保留一段時(shí)間.由于很多應(yīng)用能夠容忍讀取舊數(shù)據(jù),保留已刪除數(shù)據(jù)可進(jìn)一步提高效率.
memcache pool. memcache劃分成為分歧pool, 以應(yīng)對(duì)應(yīng)用負(fù)載的多樣性.
復(fù)制. pool內(nèi)部實(shí)現(xiàn)復(fù)制, 提高性能, 復(fù)制由客戶(hù)端控制.
處置節(jié)點(diǎn)失敗的策略:
保存大約1%節(jié)點(diǎn)組成一個(gè)Gutter集群, 當(dāng)memcache服務(wù)端無(wú)響應(yīng)時(shí), 轉(zhuǎn)而將數(shù)據(jù)緩存到gutter集群中. 采用gutter而不是rehash到其他節(jié)點(diǎn)的原因是避免負(fù)載不均(例如一個(gè)key承擔(dān)了20%致其他節(jié)點(diǎn)級(jí)聯(lián)失敗.
單機(jī)memcached優(yōu)化技術(shù):
使用可擴(kuò)展哈希,已經(jīng)貢獻(xiàn)到社區(qū).
多線(xiàn)程, 已經(jīng)貢獻(xiàn)到社區(qū).
每個(gè)線(xiàn)程獨(dú)立監(jiān)聽(tīng)一個(gè)UDP端口,避免沖突.
Adaptive Slab Allocator. 允許多個(gè)Slab之間相互替換內(nèi)存.
優(yōu)化之后的memcached性能驚人, 32字節(jié)GET達(dá)到1.8M次每秒( Xeon X5650 ,2.67GHZ, 12cores, 12hyperthreads, intel 82574L 千兆以太網(wǎng), memcached服務(wù)器開(kāi)了24個(gè)線(xiàn)程).
參考材料:
《scaling memcache at facebook》
Categories:存儲(chǔ)Tags:
mysql 行級(jí)binlog復(fù)制 的 attribute promotion 闡發(fā)
June 21st, 2013書(shū)包不見(jiàn)了Comments off
基本概念:
mysql在做主備復(fù)制時(shí),如果主備庫(kù)的表定義不同, 也就意味著要做異構(gòu)復(fù)制. attribute promotion 便是當(dāng)定義Binlog_Format = Row ,并且列屬性不同時(shí),slave端在apply binlog時(shí)做的結(jié)構(gòu)轉(zhuǎn)換.
依照官方文檔來(lái)說(shuō),在mysql-5.1.21版本開(kāi)始支持不同表定義之間的復(fù)制,主備上列的數(shù)目可以不同,屬性也可以不同.列數(shù)目不同,意味著master的列數(shù)目要小于等于slave的列數(shù)目,兩者的列順序要一致,slave額外的列需要有defaults值.
主要來(lái)看列屬性的分歧的情況:
在5.1版本中:
row binlog 只支持類(lèi)似于char(10) 到 char(25) 這樣的復(fù)制,不允許不同int之間的轉(zhuǎn)換,也不支持char類(lèi)型的和大對(duì)象轉(zhuǎn)換,只有在binlog中使用相同類(lèi)型表示的列屬性間可以轉(zhuǎn)換.并且只支持master端列寬小于slave端的轉(zhuǎn)換方式,而反之會(huì)導(dǎo)致truncate的轉(zhuǎn)換是不被支持的.其次所有的前綴唯一索引,必需保證主備的前綴長(zhǎng)度一致(否則會(huì)導(dǎo)致唯一性錯(cuò)誤)
5.1支持的轉(zhuǎn)換類(lèi)型 (來(lái)自官方文檔)
From (Master)
To (Slave)
BINARY CHAR
BLOB TEXT
CHAR BINARY
DECIMAL NUMERIC
NUMERIC DECIMAL
TEXT BLOB
VARBINARY VARCHAR
VARCHAR VARBINARY
5.1 不支持的轉(zhuǎn)換類(lèi)型:
INT (including TINYINT, SMALLINT, MEDIUMINT, BIGINT).
SET or ENUM.
FLOAT or DOUBLE.
All of the data types relating to dates, times, or both: DATE, TIME, DATETIME, TIMESTAMP, and YEAR.
5.5.3版本開(kāi)始,mysql依照之前mysql cluster的做法,引入了row binlog 的異構(gòu)復(fù)制
row binlog 開(kāi)始支持更多種類(lèi)的列屬性轉(zhuǎn)換:
引入新參數(shù) slave_type_conversion ,可以設(shè)置4個(gè)值 ALL_LOSSY(數(shù)據(jù)被truncate), ALL_NON_LOSSY(不必要被truncate的轉(zhuǎn)換), ALL_LOSSY,ALL_NON_LOSSY(可以兼容以上兩種轉(zhuǎn)換), EMPTY(不支持屬性轉(zhuǎn)換)
5.5 支持的轉(zhuǎn)換類(lèi)型(來(lái)自官方文檔)
Between any of the integer types TINYINT, SMALLINT, MEDIUMINT, INT, and BIGINT.
Between any of the decimal types DECIMAL, FLOAT, DOUBLE, and NUMERIC.
Between any of the string types CHAR, VARCHAR, and TEXT, including conversions between different widths.(分歧字符集列之間不支持復(fù)制, 會(huì)出現(xiàn)主備不一致的狀態(tài))
Between any of the binary data types BINARY, VARBINARY, and BLOB, including conversions between different widths.
Between any 2 BIT columns of any 2 sizes.
闡發(fā)行級(jí)binlog attribute promotion的源代碼
以下以mysql-5.5.22為例,主要的入口函數(shù)為 sql/log_event.cc 中的 Rows_log_event::do_apply_event(Relay_log_info const *rli),在打開(kāi)表并加完鎖之后必要檢查是否必要轉(zhuǎn)換.
TABLE *conv_table;
if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli),
ptr->table, &conv_table))
{
...
}
ptr->m_conv_table= conv_table;
mysql 遍歷所有binlog涉及的表,檢測(cè)主庫(kù)binlog傳過(guò)來(lái)的表信息是否和當(dāng)前slave端的表定義相吻合.如果必要進(jìn)行列屬性轉(zhuǎn)換,則為attribute promote 建立一張內(nèi)存的臨時(shí)表來(lái)完成,否則傳出的conv_table為NULL
compatible_with() 辦法流程
1. 檢測(cè)主備庫(kù)的最小列數(shù)
2. 針對(duì)這些列進(jìn)行是否能轉(zhuǎn)換的檢測(cè)can_convert_field_to()
a. 判斷field->real_type 是否相等
b. 如果real type 相等:
i. 判斷metadata是否為0,metadata的size取決于field的real type(例如固定大小的int 類(lèi)型metaData就為0,而char,varchar類(lèi)型都有)
ii. 如果metadata為0,直接返回成功,否則的話(huà)要比擬主備兩列的field size 再調(diào)用is_conversion_ok()
(i) 根據(jù)slave_type_conversion 參數(shù)來(lái)判斷是否能進(jìn)行轉(zhuǎn)換
c. 如果real type 不相等,又沒(méi)有設(shè)置slave_type_conversion(也便是采用默認(rèn)值EMPTY),返回上層錯(cuò)誤
d. 判斷不同用類(lèi)型之間能否轉(zhuǎn)換(int之間,char到text等等) 先比擬列的長(zhǎng)度 compare_length()
i. 調(diào)用 max_display_length() 辦法獲得列的最大長(zhǎng)度
再判斷列類(lèi)型能否轉(zhuǎn) is_conversion_ok()
3. 如果檢測(cè)出結(jié)果必要轉(zhuǎn)換,并且臨時(shí)表為NULL,則建立一張臨時(shí)轉(zhuǎn)換表create_conversion_table()
4. 如果檢測(cè)到列類(lèi)型不克不及轉(zhuǎn)換,向上層拋錯(cuò)
5. 設(shè)置臨時(shí)轉(zhuǎn)換表中的屬性類(lèi)型
在設(shè)置完臨時(shí)表convert table之后,真正使用是在unpack_current_row 中調(diào)用 rpl_record.cc 中的unpack_row
unpack_row () 辦法流程:
1. 根據(jù)當(dāng)?shù)乇砥鹗贾羔樅徒Y(jié)束指針,依次獲取每個(gè)屬性
a. 判斷對(duì)應(yīng)的convert_table 是否是NULL, 如果不是NULL則采用convert_table的列,否則采用原本slave 表自己的列, 暫時(shí)稱(chēng)這列為f
b. 檢測(cè)f列的bitmap,并設(shè)置null_bits 和 null_mask, 如果有需要的話(huà),設(shè)置default值
c. 調(diào)用Field::unpack 辦法,解析master傳過(guò)來(lái)的binlog數(shù)據(jù)內(nèi)容, 拷貝到f列
d. 如果是該列是轉(zhuǎn)換列那么source 和target 各自根據(jù)系統(tǒng)字符集開(kāi)辟一塊buffer, 此處是做真正的列類(lèi)型轉(zhuǎn)換, convert列和master一致,這里采用一個(gè)臨時(shí)的Copy_field做轉(zhuǎn)換,Copy_field是mysql專(zhuān)門(mén)用作列轉(zhuǎn)換的輔助類(lèi),通過(guò)分歧的source和target列類(lèi)型,設(shè)置轉(zhuǎn)換函數(shù)指針,將convert table中的數(shù)據(jù)拷貝到最終的slave對(duì)應(yīng)的列中
i. copy.set(*field_ptr, f, TRUE); 設(shè)置轉(zhuǎn)換類(lèi)的各個(gè)參數(shù),包含轉(zhuǎn)換函數(shù)
ii. (*copy.do_copy)(©); 做拷貝操作
2. 將master data 中復(fù)制用不到的那些列丟棄
3. 設(shè)置master side 的記錄長(zhǎng)度
自此attribute promotion 的主要流程完成.
更多技術(shù)交流,請(qǐng)存眷網(wǎng)易視頻云官網(wǎng)(http://vcloud.163.com/)或者網(wǎng)易視頻云官方微信(vcloud163)進(jìn)行交流與咨詢(xún)哦!
《網(wǎng)易視頻云分享:Facebook memcache優(yōu)化經(jīng)驗(yàn)》是否對(duì)您有啟發(fā),歡迎查看更多與《網(wǎng)易視頻云分享:Facebook memcache優(yōu)化經(jīng)驗(yàn)》相關(guān)教程,學(xué)精學(xué)透。維易PHP學(xué)院為您提供精彩教程。
轉(zhuǎn)載請(qǐng)注明本頁(yè)網(wǎng)址:
http://www.snjht.com/jiaocheng/11808.html