Tair-Storage接口阅读
Tair是淘宝的一个kv型数据库,自带容灾扩容复制等功能。内嵌mdb(memcache?),fdb(文件),kdb,ldb(levelDB)等众多开源数据库产品实现。传说还有rdb(Redis),不过rdb还没有出现在trunk中。
在此对于其存储部分(src/storage)的接口进行分析,以待后用。
以下都是基于tair-2.3版本进行的分析,ruohai | 2011-09-29 23:55:11 | tair-2.3.tar.gz | 588.3 KB
src/storage主要包含3个实体,storage_manager,dump_manager以及dump_filter。
storage_manager:存储管理的接口,所有的db都要实现该接口(相当于所有存储db的使用接口)。部分有默认实现的接口(包括暂未实现),估计都是比较新的版本引入的所以都有默认实现。
1 // 用于迁移的dump索引 2 typedef struct _migrate_dump_index 3 { 4 uint32_t hash_index; 5 uint32_t db_id; 6 bool is_migrate; 7 } md_info; 8 9 class storage_manager { 10 public: 11 storage_manager():bucket_count(0) { } 12 13 virtual ~ storage_manager() { } 14 15 /** 16 * 操作api 17 */ 18 19 // 存储key-value, version_care:是否关心版本一致性; expire_time:过期时间 20 virtual int put(int bucket_number, data_entry & key, data_entry & value, bool version_care, int expire_time) = 0; 21 22 // 通过key获取value, with_stat:? 23 virtual int get(int bucket_number, data_entry & key, data_entry & value, bool with_stat = true) = 0; 24 25 // 删除key, version_care:是否关心版本一致性 26 virtual int remove(int bucket_number, data_entry & key, bool version_care) = 0; 27 28 // [暂未实现]批量update操作 29 virtual int direct_mupdate(int bucket_number, const std::vector<operation_record*>& kvs) { return TAIR_RETURN_NOT_SUPPORTED; } 30 31 // [暂未实现]批量put操作 32 virtual int batch_put(int bucket_number, int area, tair::common::mput_record_vec* record_vec, bool version_care) { return TAIR_RETURN_NOT_SUPPORTED; } 33 34 // [暂未实现]范围查找,包含偏移量和数量限制 35 virtual int get_range(int bucket_number,data_entry & key_start,data_entry & key_end, int offset, int limit, int type, std::vector<data_entry*> &result, bool &has_next){return TAIR_RETURN_NOT_SUPPORTED;} 36 37 // [暂未实现]原子计数器? ldb并未实现 38 virtual int add_count(int bucket_num,data_entry &key, int count, int init_value, bool allow_negative,int expire_time,int &result_value) { return TAIR_RETURN_NOT_SUPPORTED; } 39 40 /** 41 * 桶操作 42 */ 43 44 // 初始化桶 45 virtual bool init_buckets(const std::vector<int> &buckets) = 0; 46 47 // 关闭(删除)桶 48 virtual void close_buckets(const std::vector<int> &buckets) = 0; 49 50 // 设置桶数量,默认实现不允许调整桶的数量 51 virtual void set_bucket_count(uint32_t bucket_count) 52 { 53 if(this->bucket_count != 0) 54 return; //can not rest bucket count 55 this->bucket_count = bucket_count; 56 return; 57 } 58 59 /** 60 * 数据迁移部分 61 */ 62 63 // 通过迁移dump索引,获取后面一部分数据 64 virtual bool get_next_items(md_info & info, std::vector<item_data_info *> &list) = 0; 65 66 // 初始化迁移dump索引 67 virtual void begin_scan(md_info & info) = 0; 68 69 // 结束迁移dump索引 70 virtual void end_scan(md_info & info) = 0; 71 72 // 73 virtual void get_stats(tair_stat * stat) = 0; 74 75 // 获取key对应的元数据 76 virtual int get_meta(data_entry &key, item_meta_info &meta) { return TAIR_RETURN_NOT_SUPPORTED; } 77 78 // Every storage engine can implement own remote synchronization logger to 79 // make use of its specific feature(eg, cache can have less strict data consistency 80 // where memory queue can be afford; permanence storage engine can direct use its 81 // bigLog). 82 virtual tair::common::RecordLogger* get_remote_sync_logger() { 83 return NULL; 84 } 85 86 /** 87 * area部分: 88 * area是数据的逻辑分区,可以针对area进行配额,也可以短期清除一个area 89 * 参考:http://www.csdn.net/article/a/2012-12-01/2812398 90 */ 91 92 // 清理area? 93 virtual int clear(int area) = 0; 94 // 设置area的容量 95 virtual void set_area_quota(int area, uint64_t quota) = 0; 96 // 批量设置area的容量 97 virtual void set_area_quota(std::map<int, uint64_t> "a_map) = 0; 98 99 /** 100 * 标志位flag操作, 个人认为都仅仅是当作工具函数来使用 101 */ 102 103 // Different storage engine reserve different amount of bits for value flag, 104 // we don't want to depend on the shortest bucket, so storage engine should 105 // implement its flag operation(may use some trick etc.) based on own bit resource. 106 // If one engine allocs too few bits to hold all flags, it is just deserved that this engine 107 // can not support all storage feature. 108 109 // use bit operation default 110 virtual bool test_flag(uint8_t meta, int flag) 111 { 112 return (meta & flag) != 0; 113 } 114 virtual void set_flag(uint8_t& meta, int flag) 115 { 116 meta |= flag; 117 } 118 virtual void clear_flag(uint8_t& meta, int flag) 119 { 120 meta &= ~flag; 121 } 122 // 将字符串型的操作给到db里面,进行处理。各db实现的不同,ldb实现了flush,reset等。 123 virtual int op_cmd(ServerCmdType cmd, std::vector<std::string>& params) { return TAIR_RETURN_SUCCESS; } 124 protected: 125 uint32_t bucket_count; // 桶数量 126 127 };
dump_manager是负责转储(dump)的模块,应该是用在作持久化,或者数据迁移、复制等场景下。而dump_filter才是真正的执行者。
1 /** 2 * dump_filter可以设置 3 * start_time,end_time,这两个时间是用来筛选被dump数据的范围的。被dump数据必须是在两个时间之内修改过的 4 * area设置被转储的数据分区,area为-1,代表对于所有的area 5 * dir是数据存储位置 6 */ 7 class dump_filter { 8 public: 9 dump_filter(); 10 dump_filter(const dump_filter &); 11 void set_parameter(uint32_t start_time, uint32_t end_time, int32_t area, const std::string & dir); 12 bool operator <(const dump_filter & rv) const; 13 14 private: 15 //this key should been decodeArea 16 // do_dump函数,对于一个key-value判断是否需要转储,需要的话,序列化到磁盘上。 17 // 只有当无法写入磁盘的时候(创建文件夹失败或者文件失败)才会返回false,不然都是true 18 bool do_dump(const data_entry & key, const data_entry & value, uint32_t area); 19 void end_dump(bool cancle); 20 void turn_interval(uint32_t now); 21 bool should_be_kept(uint32_t area, uint32_t modify_time) const; 22 // ... 23 friend class dump_thread; // 只有dump_thread可以调用私有方法... 24 }; 25 26 /** 27 * 用于dump的线程 28 */ 29 class dump_thread:public tbsys::CDefaultRunnable { 30 public: 31 dump_thread(const std::set<dump_filter> &dump_filters, const std::set<uint32_t> &bucket, uint32_t now, storage_manager * storage_mgr); 32 // 将所有符合的数据都转存到磁盘上 33 void run(tbsys::CThread * thread, void *arg); 34 void cancle(); 35 bool is_alive() const; 36 // ... 37 }; 38 39 /** 40 * dump_manager:用于管理dump的线程们 41 */ 42 class dump_manager { 43 public: 44 explicit dump_manager(storage_manager *); 45 // 简单的调用一个新的dump_thread... 46 void do_dump(const std::set<dump_filter> &dump_filters, const std::set<uint32_t> &bucket, uint32_t now); 47 void cancle_all(); 48 bool is_all_stoped(); 49 private: 50 dump_manager(const dump_manager &); 51 dump_manager & operator =(const dump_manager &); 52 void release_reference(); // 用于释放已经结束的dump线程 53 };
dump_manager等转储的逻辑仅仅在 src/dataserver/tair_manager 中被调用,其仅仅在收到dump命令时被调用。

浙公网安备 33010602011771号