網(wǎng)上有很多關(guān)于pos機(jī)地區(qū)代碼查詢,200 行代碼解讀國產(chǎn)數(shù)據(jù)庫阿里 OceanBase 的速度源頭的知識(shí),也有很多人為大家解答關(guān)于pos機(jī)地區(qū)代碼查詢的問題,今天pos機(jī)之家(www.rcqwhg.com)為大家整理了關(guān)于這方面的知識(shí),讓我們一起來看下吧!
本文目錄一覽:
pos機(jī)地區(qū)代碼查詢
【CSDN 編者按】10 月 2 日,國際事務(wù)處理性能委員會(huì)公布了數(shù)據(jù)庫最新性能測試結(jié)果,在 TPC-C 基準(zhǔn)測試中,由阿里巴巴集團(tuán)螞蟻金服自主研發(fā)的分布式關(guān)系數(shù)據(jù)庫 OceanBase 打破了由 Oracle 保持了 9 年的 TPC-C 基準(zhǔn)性能測試世界紀(jì)錄,不僅成為首個(gè)登榜的中國數(shù)據(jù)庫,更一舉拿下世界第一,對(duì)此,中國工程院院士、計(jì)算機(jī)專家李國杰評(píng)價(jià)道:「這是中國基礎(chǔ)軟件取得的重大突破!」本文作者 CSDN 博客專家馬超對(duì) OceanBase 的物理架構(gòu)、數(shù)據(jù)及控制流程進(jìn)行了分析,并解讀開源部分的源碼來剖析 OceanBase 是如何勇奪 TPC-C 冠軍的。作者 | 馬超,CSDN 博客專家
責(zé)編 | 唐小引
出品 | CSDN 博客
封圖 | CSDN 付費(fèi)下載自東方 IC
我國高科技基礎(chǔ)平臺(tái)又有重大突破,繼阿里和騰訊以及眾多國內(nèi)老牌嵌入式廠商相繼宣傳開源 IoT 操作系統(tǒng)之后,今天據(jù)權(quán)威機(jī)構(gòu)國際事務(wù)處理性能委員會(huì)(Transaction Processing Performance Council)官網(wǎng)披露,由阿里巴巴集團(tuán)螞蟻金服自主研發(fā)的關(guān)系數(shù)據(jù)庫 OceanBase,在 TPC-C 基準(zhǔn)測試中,打破了由美國公司 Oracle(甲骨文)保持了 9 年之久的世界記錄,成為首個(gè)登頂該榜單的中國數(shù)據(jù)庫產(chǎn)品。
不過經(jīng)筆者剛剛多次嘗試,目前 TPC 的官網(wǎng)(www.tpc.org)并無法在國內(nèi)訪問,所以全部的信息只能出自這個(gè)截圖,我們可以看到如下兩個(gè)信息,一是這個(gè)排行榜是以 tpmC 為基準(zhǔn)進(jìn)行排名的,這里解釋一下 tpmC 其實(shí)是 TPC-C 三標(biāo)準(zhǔn)的一種度量方式,tpmC 中的 tpm 是 transactions per minute 的簡寫,即每分鐘的交易量,C 代表 C 基準(zhǔn)程序。它的定義是每分鐘內(nèi)系統(tǒng)處理的新訂單個(gè)數(shù)。在這方面阿里的 OceanBase 的確是遙遙領(lǐng)先。
TPC-C 還經(jīng)常以系統(tǒng)性能價(jià)格比的方式體現(xiàn),單位是$/tpmC,即以系統(tǒng)的總價(jià)格(單位是美元)/tpmC 數(shù)值得出。這個(gè)筆者也已經(jīng)在上圖中標(biāo)紅,可見這個(gè)參數(shù)按現(xiàn)行匯率來說阿里的優(yōu)勢(shì)不明顯。而且考慮到甲骨文的測試提交時(shí)間是 2011 年,而阿里的測試時(shí)間則是今年的 10 月 2 日。因此由于筆者也沒拿到測試報(bào)告的原文,所以甲骨文是否還是以 11 年的硬件價(jià)格來做為分母計(jì)算性價(jià)比指標(biāo)也尚不得而知。
因而綜上所述,阿里在性能指標(biāo)上的確是做到了遙遙領(lǐng)先,但是可能在硬件價(jià)格以及測試時(shí)間的方面占了一些先機(jī)。
OceanBase 在哪些方面做對(duì)了?
根據(jù) OceanBase 的官網(wǎng)[1]介紹,其總體物理架構(gòu)如下:
同時(shí),從官網(wǎng)信息我們可以看到,OceanBase 在金融行業(yè)的應(yīng)用案例為南京銀行,因此筆者第一時(shí)間翻了一下南京銀行朋友的票圈,了解了一下相關(guān)信息,目前南京分行在 OceanBase 上線的系統(tǒng)以互聯(lián)網(wǎng)應(yīng)用為主,而且根據(jù)其分享 OceanBase 在 GitHub 對(duì)自己的 0.4 版本進(jìn)行了開源[2],目前雖然版本有更新,但是其基礎(chǔ)設(shè)計(jì)沒有根本改變,根據(jù) GitHub 上的資源顯示,其數(shù)據(jù)及控制流程總體如下:
OceanBase 將表的數(shù)據(jù)動(dòng)態(tài)切分為 tablet,tablet 的數(shù)據(jù)分為動(dòng)態(tài)和靜態(tài)兩部分。靜態(tài)的數(shù)據(jù)存放在 chunkserver 上,所有對(duì)數(shù)據(jù)的修改都存儲(chǔ)在 updateserver 中。updateserver 的修改定期同步到 chunkserver,chunkserver 將 updateserver 的更新和本地的靜態(tài)數(shù)據(jù)合并,生成合并后的新數(shù)據(jù)。
tablet 的信息由 rootserver 維護(hù),客戶端在初始化時(shí)會(huì)請(qǐng)求 rootserver,獲取 updateserver 的地址信息。客戶端的更新請(qǐng)求(包括新增、修改和刪除)都直接訪問 updateserver。查詢請(qǐng)求時(shí)客戶端根據(jù)相應(yīng)的 rowkey 向 rootserver 查詢其對(duì)應(yīng)的 tablet 信息,rootserver 返回相應(yīng)的 mergeserver 地址,客戶端根據(jù)返回的信息請(qǐng)求相應(yīng)的 mergeserver 獲取數(shù)據(jù)。
Mergeserver 收到請(qǐng)求時(shí),根據(jù) rowkey 從 rootserver 獲取相應(yīng)的 tablet 信息,該信息中包括負(fù)責(zé)該 tablet 的 chunkserver 列表,mergeserver 請(qǐng)求相應(yīng)的 chunkserver,獲取靜態(tài)數(shù)據(jù)(如果有的話),然后根據(jù)返回的數(shù)據(jù),請(qǐng)求 updateserver 獲取相應(yīng)的更新數(shù)據(jù),將更新數(shù)據(jù)和靜態(tài)的數(shù)據(jù)合并,將合并后的結(jié)果返回給客戶端。
為了提高讀取的性能,chunkserver 對(duì)部分?jǐn)?shù)據(jù)結(jié)構(gòu)進(jìn)行了緩存。一個(gè) SSTable 由多個(gè) block 組成,為了加快定位需要請(qǐng)求的數(shù)據(jù)位于 SSTable 的哪個(gè) block 中,chunkserver 包含一個(gè) block index 的功能,block index 由該 block 負(fù)責(zé)的數(shù)據(jù)的最后一個(gè) key 和該 block 在 SSTable 文件中的位置組成。為了提高 block 的讀取性能,chunkserver 還將 block 緩存在內(nèi)存中。Block index 和 block 的 cache 都采用 LRU 的策略淘汰。
筆者之前的博文中也介紹過,想提高效率必須做做減法,針對(duì)專門的場景做特定的優(yōu)化。在筆者看到 OceanBase 的設(shè)計(jì)時(shí),最令我印象深刻的是其 chunkserver 自帶的緩存功能,而且根據(jù)之前的最佳實(shí)踐分享,與甲骨文等傳統(tǒng)數(shù)據(jù)庫不同,OceanBase 與應(yīng)用之間是不需要加 redius 緩存的,所以這點(diǎn)應(yīng)該是阿里做的比傳統(tǒng)數(shù)據(jù)庫廠商厲害的地方。阿里的數(shù)據(jù)庫之所以快基本上可以歸功于這個(gè) chunkserver 的功勞,下面我們就來進(jìn)行一下代碼解讀。
速度秘訣:chunkserver 的設(shè)計(jì)與相關(guān)代碼
其 chunkserver 的基礎(chǔ)流程圖如下:
可以看到負(fù)責(zé)數(shù)據(jù)查找和讀取的部分是 SSTable 所以下面我們?cè)賹?duì)這部分做一下詳細(xì)的代碼解讀,為便于查找,SSTable 會(huì)建立一些信息來索引數(shù)據(jù),比如相關(guān) key 在 SSTable 中的偏移,IndexBuilder 即用來建立這些信息。這部分的相關(guān)代碼在:
https://github.com/alibaba/oceanbase/tree/master/oceanbase_0.4/src/sstable/ob_sstable_block_index_builder.cpp
其中重點(diǎn)函數(shù)是這個(gè)生成入口的函數(shù) add_entry,這些都寫得比較清楚,大家可以看一下。
int ObSSTableBlockIndexBuilder::add_entry(const uint64_t table_id,const uint64_t column_group_id,const ObRowkey &key,const int32_t record_size){int ret = OB_SUCCESS;ObSSTableBlockIndexItem index_item;//合法性校驗(yàn)if (record_size < 0 || key.get_obj_cnt <= 0 || == key.get_obj_ptr|| table_id == OB_INVALID_ID || table_id == 0 || OB_INVALID_ID == column_group_id){TBSYS_LOG(WARN, "invalid param, table_id=%lu, key_len=%ld,""key_ptr=%p, record_size=%d, column_group_id=%lu",table_id, key.get_obj_cnt, key.get_obj_ptr, record_size, column_group_id);ret = OB_ERROR;}if (OB_SUCCESS == ret){//初始化,后面也是用以下的參數(shù)進(jìn)行序列化的index_item.rowkey_column_count_ = static_cast<int16_t>(key.get_obj_cnt);index_item.column_group_id_ = static_cast<uint16_t>(column_group_id);index_item.table_id_ = static_cast<uint32_t>(table_id);index_item.block_record_size_ = record_size;index_item.block_end_key_size_ = static_cast<int16_t>(key.get_serialize_objs_size);index_item.reserved_ = 0;ret = index_items_buf_.add_index_item(index_item);if (OB_SUCCESS == ret){ret = end_keys_buf_.add_key(key);if (OB_ERROR == ret){TBSYS_LOG(WARN, "failed to add end key");}else{index_block_header_.sstable_block_count_++;}}else{TBSYS_LOG(WARN, "failed to add index item");ret = OB_ERROR;}}return ret;}
和這個(gè)函數(shù)生成 index 的函數(shù):
int ObSSTableBlockIndexBuilder::build_block_index(const bool use_binary_rowkey, char* index_block, const int64_t buffer_size, int64_t& index_size){int ret = OB_SUCCESS;int64_t index_block_size = get_index_block_size;int64_t index_items_size = get_index_items_size;int64_t header_size = index_block_header_.get_serialize_size;int64_t pos = 0;if ( == index_block){TBSYS_LOG(WARN, "invalid param, index_block=%p", index_block);ret = OB_ERROR;}else if (index_block_size == header_size){//no data in index blockret = OB_ERROR;}if (OB_SUCCESS == ret){index_block_header_.end_key_char_stream_offset_= static_cast<int32_t>(header_size + index_items_size);// new rowkey obj array format, force set to 1.index_block_header_.rowkey_flag_ = use_binary_rowkey ? 0 : 1;if (OB_SUCCESS == index_block_header_.serialize(index_block,header_size, pos)){char* ptr = index_block + pos;ret = index_items_buf_.get_data(ptr, buffer_size - header_size);if (OB_SUCCESS == ret){ptr += index_items_size;ret = end_keys_buf_.get_data(ptr, buffer_size - header_size - index_items_size);if (OB_SUCCESS == ret){index_size = index_block_size;}}}else{TBSYS_LOG(WARN, "failed to serialize index block header");ret = OB_ERROR;}}return ret;}
并且,除了索引以外,OceanBase 還在讀取之前添加了一個(gè)布隆過濾器,這個(gè)設(shè)計(jì)也比較有意思,Bloom Filter(布隆過濾器)用來判定某一個(gè) key 是否屬于某個(gè)集合,它有一定誤判概率。如果判定在集合內(nèi),不一定在;但是如果判定不在集合內(nèi),那么一定不在,這樣的操作可以優(yōu)化很多 not in 的查詢時(shí)間。這部分的代碼在:
https://github.com/alibaba/oceanbase/tree/master/oceanbase_0.4/src/common/bloom_filter.h
https://github.com/alibaba/oceanbase/tree/master/oceanbase_0.4/src/common/bloom_filter.cpp
這里就不再貼代碼了,大家有興趣可以去上面的鏈接讀一下相關(guān)代碼。
后記
隨著美國在高科技領(lǐng)域的不斷施壓,反而倒逼我國之前相對(duì)冷清的操作系統(tǒng)、數(shù)據(jù)庫等基礎(chǔ)平臺(tái)領(lǐng)域重新熱鬧起來,筆者這個(gè) C 語言的 IT 老兵感覺目前又煥發(fā)第二春,所以筆者還會(huì)繼續(xù)關(guān)注相關(guān)領(lǐng)域的進(jìn)展,后續(xù)繼續(xù)帶來代碼級(jí)的解讀,歡迎持續(xù)關(guān)注。
[1] https://oceanbase.alipay.com/product/oceanbase
[2] https://github.com/alibaba/oceanbase
掃描下方二維碼,下載 CSDN App,與博主互動(dòng)起來!
【END】
以上就是關(guān)于pos機(jī)地區(qū)代碼查詢,200 行代碼解讀國產(chǎn)數(shù)據(jù)庫阿里 OceanBase 的速度源頭的知識(shí),后面我們會(huì)繼續(xù)為大家整理關(guān)于pos機(jī)地區(qū)代碼查詢的知識(shí),希望能夠幫助到大家!