(3分シリーズ)Redisにおける辞書の内部原理と使用方法を詳しく解く
3865 ワード
前言
Redisでは、辞書は特に広く使われているデータ構造で、基本的に各機能モジュールで使用されています。
目次
1.辞書の使用例
1.1データベースキースペースの実現
redis> FLUSHDB
OK
redis> DBSIZE
(integer) 0
redis> set space dong
OK
redis> get space
"dong"
以上の3つは,辞書がRedisデータベース内でキー空間として用いられる例であり,データベースを操作するコマンドは,実際には辞書上で操作される.
1.2 Hashタイプキーの下位実装
Hashキーの下部には2つのデータ構造があり、1つは圧縮リストであり、1つは辞書のデフォルトは圧縮リストによって実現され、条件が満たされるまで変換が実現されない.
条件:
redis> HSET spacedong redis "redis"
(integer) 1
redis> HSET spacedong mysql "mysql"
(integer) 1
redis>HSET spacedong memcached "memcached"
(integer) 1
redis> HGETALL spacedong
1) "mysql"
2) "mysql"
3) "redis"
4) "redis"
5) "memcached"
6) "memcached"
2.辞書の下位構造とソースコードの解析
2.1辞書の構造
/*
*
*
* , rehash
*/
typedef struct dict {
//
dictType *type;
//
void *privdata;
// (2 )
dictht ht[2];
// rehash , -1 rehash
int rehashidx;
//
int iterators;
} dict;
2.2 Hashテーブルの構成
/*
*
*/
typedef struct dictht {
// ( ,bucket)
dictEntry **table;
//
unsigned long size;
// ,
unsigned long sizemask;
//
unsigned long used;
} dictht;
2.3 DictEntryの構成
typedef struct dictEntry {
//
void *key;
//
union {
void *val;
uint64_t u64;
int64_t s64;
} v;
// ,
struct dictEntry *next;
} dictEntry;
2.3キー競合の解決
hashテーブルにキー競合が発生した場合、Redisでの処理は、挿入されたこのキーのnextポインタを現在のキーに直接指向し、一般的にはこのノードのヘッダに直接挿入し、チェーンテーブルを形成することである.
3.Rehashプロセス
3.1以下のReHashの前提条件のいずれかを満たすと拡張Hashテーブルが行われる
補足:
サーバがBGSAVEまたはBGREWRITEAOFのコマンドを実行している場合、このときサーバはサブプロセスを作成してバックアップを完了し、オペレーティングシステムは一般的に書き込み時にコピーした(copr-on-write)を使用してサブプロセスの効率を向上させるため、サブプロセス実行中に負荷因子を拡大し、サブプロセスが存在する間に拡張テーブルを行うことを可能な限り回避し、不要なメモリ消費を低減することができる。
負荷係数(load_factor)=既存のノード数収容可能なノード数
3.2 Rehashプロセス
4.実際の運用シーン分析
以上の辞書の特性から,辞書とHashMapの特性は差が少なく,配列とチェーンテーブルの組合せにも基づいていることが分かるので,一般的にキー値ペアを格納するために用いられる.しかし、実際の運用シーンでは、オブジェクトの情報を格納するためによく使用されます.例えば、name、age、weightなどのオブジェクトの属性は、この辞書に直接キー値として格納できる利点は、このオブジェクトの属性を使用する必要がある場合、このオブジェクトをすべてシーケンス化する必要はなく、特定のものを取り出すだけでよいが、従来のすべてのシーケンス化が必要である場合に比べてリソースを消費することである.
参考書:Redisの設計と実現