Redis のビットマップの詳細な分析 (ビットマップ)

青灯夜游
リリース: 2021-12-02 10:17:18
転載
4930 人が閲覧しました

この記事では Redis のビットマップについて説明します。お役に立てば幸いです。

Redis のビットマップの詳細な分析 (ビットマップ)

Redis のビットマップは、複数のバイナリ ビットで構成される配列です。配列内の各バイナリ ビットには、対応するオフセット (0 から開始) があり、これらのオフセットを使用できます。ビットマップで指定された 1 つ以上のバイナリ ビットを操作します。 [関連する推奨事項: Redis ビデオ チュートリアル ]

実際には、ビットマップは Redis によって提供される新しいデータ型ではなく、文字列型の拡張です。したがって、文字列型のキーに対してビットマップコマンドを直接使用することができ、ビットマップコマンドで操作したキーを文字列型のコマンドでも操作することができます。

たとえば、文字列キー foo があります:

redis> set foo bar
ログイン後にコピー

1 バイトは 8 バイナリ ビットで構成されているため、foo キーのバイナリ形式は次のようになります:

Redis のビットマップの詳細な分析 (ビットマップ)

#SETBIT

SETBIT コマンドを使用して、ビットマップのオフセットにバイナリ ビット設定値を指定できます。オフセットは次の値より大きくする必要があります。 0 またはそれに等しい場合、値は 0 または 1 のみです。このコマンドの時間計算量は O(1) です。

SETBIT キー オフセット値

バイナリ ビットを設定した後、SETBIT コマンドはバイナリ ビットが設定される前の古い値を結果として返します。

bar を aar に変更したいとします。次の 2 つの手順を実行するだけで済みます。

redis> setbit foo 6 0
(integer) 1
redis> setbit foo 7 1
(integer) 0
redis> get foo"aar"
ログイン後にコピー

SETBIT コマンドを実行してビットマップを設定しようとするとき、ビットマップが設定されている場合は、存在しない、またはビットマップの現在のサイズを満足できない場合、Redis は設定されたビットマップを拡張し、未設定のすべてのバイナリ ビットの値を 0 に初期化します。例:

redis> setbit far 10 1
ログイン後にコピー

far が存在しないため、Redis はバイナリ ビットを 0 から 9 まで 0 に設定します。Redis はビットマップをバイト単位で拡張するため、実際には far バイナリ ビットは 10 ではなく、合計 16 です。 、バイナリのビット 11 ~ 15 も 0 です。

この状況に基づいて、指定されたバイナリ ビット オフセットが大きすぎる場合、Redis はすべてのメモリを一度に割り当てる必要があり、Redis サーバーがブロックされる可能性があります。たとえば、ユーザーの性別を保存する場合、ID をバイナリ オフセットとして使用して、1 は男性を表し、0 は女性を表します。ID が 10000000001 から始まる場合は、保存する前にユーザー ID から 10000000000 を減算する必要があります。そうしないと、データの無駄が発生します。メモリ。

GETBIT

GETBIT コマンドを使用して、ビットマップの指定されたオフセットにあるバイナリ ビットの値を取得します。このコマンドの時間計算量は O(1) です。

GETBIT キー オフセット

入力されたオフセットが、ビットマップが現在所有している最大オフセットを超える場合、結果として 0 が返されます。

BITCOUNT

BITCOUNT コマンドを使用すると、ビットマップ内の値 1 を持つバイナリ ビットの数をカウントできます。このコマンドの時間計算量は O(n) です。

BITCOUNT キー [開始終了]

デフォルトでは、BITCOUNT コマンドはビットマップに含まれるすべてのバイトのバイナリ ビットをカウントします。 start パラメータと end パラメータを使用して、BITCOUNT が指定された

byte 範囲内のバイナリ ビットのみをカウントできるようにします (バイナリ オフセットではありません)。たとえば、ar の 2 バイトで値が 1 の 2 進数の数をカウントしたい場合:

redis> bitcount foo 1 2
(integer) 7
ログイン後にコピー

start パラメータと end パラメータでは、負のインデックスの使用もサポートされています。以下の使用法は次と同等です。上記:

redis> bitcount foo -2 -1
(integer) 7
ログイン後にコピー

BITPOS

BITPOS コマンドを実行して、ビットマップ内の指定された値に設定された最初のバイナリ ビットを見つけて返します。このバイナリ ビットのオフセット。

BITPOS キー値 [開始終了]

BITPOS はオプションの開始パラメータと終了パラメータも受け入れ、BITPOS コマンドで

bytes## のみを指定できるようにします # 検索範囲内のバイナリビットで。

redis> get foo"aar"redis> bitpos foo 1
(integer) 1
redis> bitpos foo 0
(integer) 0
redis> bitpos foo 0 1 2
(integer) 8
redis> bitpos foo 1 1 2
(integer) 9
redis> bitpos foo 1 -1 -1
(integer) 17
ログイン後にコピー
境界の処理:

存在しないビットマップ、またはすべてのビットが 0 ビットに設定されたビットマップでバイナリ値 1 を検索しようとすると、BITPOS コマンドが使用されます。結果として -1 が返されます。
  • すべてのビットが 1 に設定されているビットマップ内で値 0 のバイナリ ビットが見つかった場合、BITPOS コマンドは結果としてビットマップの最大オフセットに 1 を加えた値を返します

BITOPBITOP コマンドを使用して、1 つ以上のビットマップに対して指定されたバイナリ ビット演算を実行し、演算結果を指定されたキーに保存します。

BITOP 操作 destkey key [key ...]

operation 参数的值可以是 AND、OR、XOR、NOT 中的任意一个,这 4 个值分别对应逻辑并、逻辑或、逻辑异或和逻辑非 4 种运算,其中 AND、OR、XOR 这 3 种运算允许用户使用任意数量的位图作为输入,而 NOT 运算只允许使用一个位图作为输入。BITOP 命令在将计算结果存储到指定键中之后,会返回被存储位图的字节长度。

当 BITOP 命令在对两个长度不同的位图执行运算时,会将长度较短的那个位图中不存在的二进制位的值看作 0。

redis> set foo1 bar
OK
redis> set foo2 aar
OK
redis> bitop or res foo1 foo2
(integer) 3
redis> get res"car"
ログイン後にコピー

Redis のビットマップの詳細な分析 (ビットマップ)

注意:BITOP 可能是一个缓慢的命令,它的时间复杂度是 O(N),在处理长字符串时应注意一下效率问题。

应用场景

用户行为记录器

用用户 ID 作为偏移量,若用户做了某种行为则通过 SETBIT 将二进制位设置为 1,通过 GETBIT 判断用户是否做了某种行为,通过 BITCOUNT 可以知道有多少用户执行了行为。

用户上线统计

可以使用 SETBIT 和 BITCOUNT 来实现,以用户 ID 作为 key ,假设今天是上线统计功能开放的第一天,ID 为 1 的用户上线后就通过 SETBIT 1 0 1。当要计算此用户的总共以来的上线次数时,使用 BITCOUNT 命令就可以得出的结果。

使用这种方式存储数据,即使 10 年后,1个用户就只占用几百字节的内存,它的处理速度依然很快。如果 bitmap 数据比较大,建议将 bitmap 拆分成多个小的 bitmap 分别进行处理。

更多编程相关知识,请访问:编程入门!!

以上がRedis のビットマップの詳細な分析 (ビットマップ)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!