Redis は優れたパフォーマンスを備えたインメモリ データベースですが、使用中に Big Key 問題が発生する可能性があります。この問題は Redis の特定のキーに発生します。が大きすぎるため、Big Key 問題は本質的に Big Value 問題 となり、Redis のパフォーマンス低下またはクラッシュが発生します。
Redis では、各キーに対応する値があります。キーの値が大きすぎると、Redis のパフォーマンスが低下したりクラッシュしたりする原因になります。 Redis はすべての大きなキーをメモリにロードする必要があるため、多くのメモリ領域を占有し、Redis の応答速度が低下します。この問題はビッグ キー問題と呼ばれます。この問題を過小評価しないでください。Redis が即座に「カメ」に変わる可能性があります。Redis のシングルスレッドの性質により、Big Key の操作には通常時間がかかります。これは、Redis をブロックする可能性がより高いことを意味します。クライアントがブロックされるかフェイルオーバーが発生し、「クエリの遅延」が発生する可能性があります。
一般に、次の 2 つの状況をラージ キーと呼びます。
String 型キーに対応する値が 10 MB を超えている。
list、set、hash、zset などのコレクション型、コレクション要素の数が 5000 を超えています。
Big Key の判断基準は上記が唯一のものではなく、あくまでも目安です。実際の事業展開において大きな鍵となるかどうかは、具体的なアプリケーションシナリオに応じて判断する必要があります。特定のキーの操作によってリクエストの応答時間が遅くなる場合、そのキーは Big Key であると判断できます。
Redis では、通常、キーが大きくなるのは次の理由が原因です。:
シリアル化後のオブジェクトのサイズが大きすぎる大
大きなキーの問題のトラブルシューティング
BIGKEYS コマンドを使用する
コマンドはデータベース全体をスキャンします。このコマンド自体が Redis をブロックし、すべてのビッグ キーを見つけて、次の形式でクライアントに返します。リスト。 コマンドの形式は次のとおりです:
$ redis-cli --bigkeys
戻り値の例は次のとおりです:
# Scanning the entire keyspace to find biggest keys as well as # average sizes per key type. You can use -i 0.1 to sleep 0.1 sec # per 100 SCAN commands (not usually needed). [00.00%] Biggest string found so far 'a' with 3 bytes [05.14%] Biggest list found so far 'b' with 100004 items [35.77%] Biggest string found so far 'c' with 6 bytes [73.91%] Biggest hash found so far 'd' with 3 fields -------- summary ------- Sampled 506 keys in the keyspace! Total key length in bytes is 3452 (avg len 6.82) Biggest string found 'c' has 6 bytes Biggest list found 'b' has 100004 items Biggest hash found 'd' has 3 fields 504 strings with 1403 bytes (99.60% of keys, avg size 2.78) 1 lists with 100004 items (00.20% of keys, avg size 100004.00) 0 sets with 0 members (00.00% of keys, avg size 0.00) 1 hashs with 3 fields (00.20% of keys, avg size 3.00) 0 zsets with 0 members (00.00% of keys, avg size 0.00)
コマンドには
BIGKEYS が必要であることに注意してください。データベース全体をスキャンすると、Redis インスタンスに一定の負荷がかかる可能性があります。 このコマンドを実行する前に、Redis インスタンスにこのコマンドを処理するのに十分なリソースがあることを確認してください。スレーブ ノードから
を実行することをお勧めします。 デバッグ オブジェクト
を使用すると、キーの値のサイズなど、キーの詳細情報を表示できます。現時点では、Redis 内を「覗いて」、どのキーが大きすぎるかを確認できます。 キーが存在する場合、Debug Object コマンドはキーに関する情報を提供するデバッグ コマンドです。キーが存在しない場合はエラーを返します。
redis 127.0.0.1:6379> DEBUG OBJECT key Value at:0xb6838d20 refcount:1 encoding:raw serializedlength:9 lru:283790 lru_seconds_idle:150 redis 127.0.0.1:6379> DEBUG OBJECT key (error) ERR no such key
serializedlength は、キーに対応する値のシリアル化後のバイト数を示します
メモリ使用量
バージョン 4.0 以降では、memory usag コマンドを使用できます。
メモリ使用量コマンドの使用は非常に簡単で、メモリ使用量のキー名を押すだけです。現在のキーが存在する場合は、キーの値の実際のメモリ使用量の推定値が返されます。キーが存在しない場合は、 , nil が返されます。
127.0.0.1:6379> set k1 value1 OK 127.0.0.1:6379> memory usage k1 //这里k1 value占用57字节内存 (integer) 57 127.0.0.1:6379> memory usage aaa // aaa键不存在,返回nil. (nil)
String型以外のメモリ使用量コマンドはサンプリング方式を採用しており、デフォルトでは5要素をサンプリングするため近似値として計算されますが、サンプル数を指定することも可能です。
説明例: 100 万フィールドのハッシュ キーを生成: hkey 各フィールドの値の長さは、1 ~ 1024 バイトのランダムな値です。
127.0.0.1:6379> hlen hkey // hkey有100w个字段,每个字段的value长度介于1~1024个字节 (integer) 1000000 127.0.0.1:6379> MEMORY usage hkey //默认SAMPLES为5,分析hkey键内存占用521588753字节 (integer) 521588753 127.0.0.1:6379> MEMORY usage hkey SAMPLES 1000 //指定SAMPLES为1000,分析hkey键内存占用617977753字节 (integer) 617977753 127.0.0.1:6379> MEMORY usage hkey SAMPLES 10000 //指定SAMPLES为10000,分析hkey键内存占用624950853字节 (integer) 624950853
より正確なキーのメモリ値を取得するには、より大きなサンプリング数を指定します。ただし、サンプル数が増えると、より多くの CPU 時間が占有されます。
redis-rdb-tools
PYPI を使用したインストール
pip install rdbtools
メモリ スナップショットの生成
rdb -c memory dump.rdb > memory.csv
生成された CSV ファイルには次の列があります:
database
key在Redis的db
type
key类型
key
key值
size_in_bytes
key的内存大小
encoding
value的存储编码形式
num_elements
key中的value的个数
len_largest_element
key中的value的长度
可以在MySQL中新建表然后导入进行分析,然后可以直接通过SQL语句进行查询分析。
CREATE TABLE `memory` ( `database` int(128) DEFAULT NULL, `type` varchar(128) DEFAULT NULL, `KEY` varchar(128), `size_in_bytes` bigint(20) DEFAULT NULL, `encoding` varchar(128) DEFAULT NULL, `num_elements` bigint(20) DEFAULT NULL, `len_largest_element` varchar(128) DEFAULT NULL, PRIMARY KEY (`KEY`) );
例子:查询内存占用最高的3个 key
mysql> SELECT * FROM memory ORDER BY size_in_bytes DESC LIMIT 3; +----------+------+-----+---------------+-----------+--------------+---------------------+ | database | type | key | size_in_bytes | encoding | num_elements | len_largest_element | +----------+------+-----+---------------+-----------+--------------+---------------------+ | 0 | set | k1 | 624550 | hashtable | 50000 | 10 | | 0 | set | k2 | 420191 | hashtable | 46000 | 10 | | 0 | set | k3 | 325465 | hashtable | 38000 | 10 | +----------+------+-----+---------------+-----------+--------------+---------------------+ 3 rows in set (0.12 sec)
当发现存在大key问题时,我们需要及时采取措施来解决这个问题。下面列出几种可行的解决思路:
将Big Key拆分成多个小的key。这个方法比较简单,但是需要修改应用程序的代码。虽然有些费力,但将一个大蛋糕切成小蛋糕可以解决问题。
或者尝试将Big Key转换成Redis的数据结构。例如,可以使用哈希表、列表或集合等数据结构将“Big Key”进行转换。
若大key的大小源于对象序列化后的体积巨大,我们可思考运用压缩算法来缩小对象的尺寸。Redis自身支持多种压缩算法,例如LZF、Snappy等。
如果你所用的Redis版本是4.0或更高版本,你可以使用unlink命令进行异步删除。4.0以下的版本 可以考虑使用 scan ,分批次删除。
无论采用哪种方法,都需要注意以下几点:
避免使用过大的value。如果需要存储大量的数据,可以将其拆分成多个小的value。就像是吃饭一样,一口一口的吃,不要贪多嚼不烂。
避免使用不必要的数据结构。如果只需要保存一个字符串,应该避免使用像Hash或List这样的数据结构。
定期清理过期的key。当Redis中存在大量过期的key时,会导致Redis性能下降。就像是家里的垃圾,需要定期清理。
对象压缩
以上がRedis の BigKey のトラブルシューティングと解決策は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。