您好,登錄后才能下訂單哦!
本篇內容主要講解“RGW的index shard計算怎么實現”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“RGW的index shard計算怎么實現”吧!
在RGW里面每個存儲到rados的Object都需要先計算出對應元數據存儲的shard number,之后再將元數據信息更新到shard number對應的Object里面。代碼如下所示
int RGWRados::get_bucket_index_object(const string& bucket_oid_base, const string& obj_key,
uint32_t num_shards, RGWBucketInfo::BIShardsHashType hash_type, string *bucket_obj, int *shard_id)
{
int r = 0;
switch (hash_type) {
case RGWBucketInfo::MOD:
if (!num_shards) {
// By default with no sharding, we use the bucket oid as itself
(*bucket_obj) = bucket_oid_base;
if (shard_id) {
*shard_id = -1;
}
} else {
uint32_t sid = ceph_str_hash_linux(obj_key.c_str(), obj_key.size());
uint32_t sid2 = sid ^ ((sid & 0xFF) << 24);
sid = sid2 % MAX_BUCKET_INDEX_SHARDS_PRIME % num_shards;
char buf[bucket_oid_base.size() + 32];
snprintf(buf, sizeof(buf), "%s.%d", bucket_oid_base.c_str(), sid);
(*bucket_obj) = buf;
if (shard_id) {
*shard_id = (int)sid;
}
}
break;
default:
r = -ENOTSUP;
}
return r;
}
有同學提問,為什么不直接寫成 sid = sid %num_shards,而是獲取到對應sid以后再做一次sid2 = sid ^ ((sid & 0xFF) << 24),下面把這段代碼截取出來說明原因。
編輯頭文件 hash_shard.h,內容如下
#ifndef hash_shard_h #define hash_shard_h #ifndef _UINT32_T #define _UINT32_T typedef unsigned int uint32_t; #endif /* _UINT32_T */ #endif /* hash_shard_h */ unsigned ceph_str_hash_linux(const char *str, unsigned long length) { unsigned long hash = 0; while (length--) { unsigned char c = *str++; hash = (hash + (c << 4) + (c >> 4)) * 11; } return hash; }
編輯 main.cpp,內容如下
#include <iostream> #include "hash_shard.h" void hash_obj(std::string obj_key){ uint32_t sid = ceph_str_hash_linux(obj_key.c_str(), obj_key.size()); uint32_t sid1 = sid ^ ((sid & 0xFF) << 24); uint32_t sid2 = sid1 % 7877 % 8; uint32_t sid3 = sid % 7877 % 8; std::cout << "hash3=" << sid2 <<std::endl; std::cout << "hash2="<< sid3 <<std::endl; } int main(int argc, const char * argv[]) { std::string obj_key1 = "aa2"; hash_obj(obj_key1); std::string obj_key2 = "aa1"; hash_obj(obj_key2); std::string obj_key3 = "aa0"; hash_obj(obj_key3); std::string obj_key4 = "aa3"; hash_obj(obj_key4); std::string obj_key5 = "aa3"; hash_obj(obj_key5); return 0; }
root@demohost:/home/demouser/hash_shard# g++ main.cpp -o hash_shard
root@demohost:/home/demouser/hash_shard# ./hash_shard
hash3=7
hash2=1
hash3=7
hash2=1
hash3=7
hash2=1
hash3=4
hash2=1
hash3=4
hash2=1
從裁剪出來的代碼運行結果來看,直接sid = sid %num_shards會導致hash計算出來的結果不夠離散,最終導致數據都集中寫到一個shard文件上造成寫入上的單點熱數據(hash2計算出來的結果都是1)。
另外MAX_BUCKET_INDEX_SHARDS_PRIME為什么是7877,可以是其他數嗎?答案是可以的,但是這個最好是質數,從而保障取余得到的結果足夠隨機。
到此,相信大家對“RGW的index shard計算怎么實現”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。