キーは通常文字列であり、文字列の基礎となるデータ構造は SDS です。SDS 構造には文字列の長さ、割り当てが含まれます。スペースサイズなどのメタデータ情報。キー文字列の長さが増加すると、SDS 内のメタデータもより多くのメモリスペースを占有します。キーが占めるスペースを減らすために、ビジネス名に応じて対応する英語の略語を使用できます。それを表すために。たとえば、ユーザーは u で表され、メッセージは m で表されます。
キーの長さと値のサイズの両方に注意する必要があります。Redis はデータの読み取りと書き込みに単一のスレッドを使用します。読み取りおよび書き込み操作bigkey を使用するとスレッドがブロックされ、コストが削減され、Redis の処理効率が向上します。
--bigkey コマンドを使用して、Redis にある bigkey 情報を表示できます。具体的なコマンドは次のとおりです:
redis-cli -h 127.0.0.1 -p 6379 -a 'xxx' --bigkeys
上の図に示すように、Redis のキーは 32098 バイトを占めており、最適化する必要があることがわかります。
推奨事項:
キーが文字列型の場合、値に格納される値のサイズは約 10KB にすることをお勧めします。 。
キーが List/Hash/Set/ZSet タイプの場合、格納される要素の数は 10,000 未満に制御することをお勧めします。
Redis は、保存するデータ型に合わせて最適化され、それに応じてメモリも最適化されます。データ結果に関する関連知識については、以前の記事を参照してください。
例: String と set は、int データを格納するときに整数エンコーディングを使用します。 Hash と ZSet は、要素の数が比較的少ない場合は圧縮リスト (ziplist) ストレージを使用し、比較的大量のデータが格納される場合はハッシュ テーブルとジャンプ テーブルに変換します。
Redis の文字列はバイナリセーフなバイト配列を使用して保存されるため、ビジネスをバイナリにシリアル化し、それを Redis に書き込むことができますが、別のシリアル化を使用すると、占有スペースが異なります。 Protostuff のシリアル化は、Java の組み込みシリアル化よりも効率的で、占有するスペースも少なくなります。スペース使用量を削減するために、JSON および XML データ形式を圧縮して保存できます。オプションの圧縮アルゴリズムには、Gzip や Snappy が含まれます。
Redis メモリが継続的に拡張されて過剰なリソース使用量が発生することを避けるために、ビジネス データの量に基づいてメモリ サイズを事前に見積もります。 。
# 消去戦略の設定方法については、実際のビジネス特性に基づいて選択する必要があります:
#volatile-lru / allkeys- lru: 最近アクセスされたデータを優先する
最も頻繁にアクセスされるデータを優先する
期限切れが近づいているデータの削除を優先します
ランダム削除データ
メモリの断片を定期的にクリアする
手順:
对于集合类型的来说,在未清楚集合数据大小的情况下,慎用查询集合中的全量数据,例如Hash的HetALL、Set的SMEMBERS命令、LRANGE key 0 -1 或者ZRANGE key 0 -1等命令,因为这些命令会对Hash或者Set类型的底层数据进行全量扫描,当集合数据量比较大时,会阻塞Redis的主线程。
优化建议:
当元素数据量较多时,可以用SSCAN、HSCAN 命令分批返回集合中的数据,减少对主线程的阻塞。
Redis执行复杂度过高的命令,会消耗更多的 CPU 资源,导致主线程中的其它请求只能等待。常见的复杂命令如下:SORT、SINTER、SINTERSTORE、ZUNIONSTORE、ZINTERSTORE 等聚合类命令。
优化建议:
当需要执行排序、交集、并集操作时,可以在客户端完成,避免让Redis进行过多计算,从而影响Redis性能。
Redis通常用于保存热数据。热数据一般都有使用的时效性。因此,在数据存储的过程中,应根据业务对数据的使用时间合理地设置数据的过期时间。否则写入Redis的数据会一直占用内存,如果数据持续增增长,会达到机器的内存上限,造成内存溢出,导致服务崩溃。
当我们需要一次性操作多个key时,可以使用批量命令来处理,批量命令可以减少客户端与服务端的来回网络IO次数。
String或者Hash类型可以使用 MGET/MSET替代 GET/SET,HMGET/HMSET替代HGET/HSET
其它数据类型使用Pipeline命令,一次性打包发送多个命令到服务端执行。
redisTemplate.executePipelined(new RedisCallback<String>() { @Override public String doInRedis(RedisConnection connection) throws DataAccessException { for (int i = 0; i < 5; i++) { connection.set(("test:" + i).getBytes(), "test".getBytes()); } return null; } });
不同的业务线来部署 Redis 实例,这样当其中一个实例发生故障时,不会影响到其它业务。
业务上根据实际情况采用主从、哨兵、集群方案,避免单点故障,影响业务的正常使用。
针对主从环境,我们需要合理设置相关参数,具体内容如下:
合理的设置repl-backlog参数:如果repl-backlog设置过小,当写流量比较大的场景下,主从复制中断可能会引发全量复制数据的风险。
合理设置slave client-output-buffer-limit:当从库复制发生问题时,过小的 buffer会导致从库缓冲区溢出,从而导致复制中断。
以上がRedis最適化例の分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。