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