Maison  >  Article  >  base de données  >  Une analyse approfondie des bitmaps dans Redis (bitmap)

Une analyse approfondie des bitmaps dans Redis (bitmap)

青灯夜游
青灯夜游avant
2021-12-02 10:17:184926parcourir

Cet article vous présentera le bitmap dans Redis. J'espère qu'il vous sera utile !

Une analyse approfondie des bitmaps dans Redis (bitmap)

Le bitmap de Redis est un tableau composé de plusieurs bits binaires. Chaque bit binaire du tableau a un décalage correspondant (à partir de 0, vous pouvez opérer sur un ou plusieurs bits binaires spécifiés dans le). bitmap. [Recommandations associées : Tutoriel vidéo Redis]

En fait, le bitmap n'est pas un nouveau type de données fourni par Redis, c'est une extension du type chaîne. Par conséquent, les commandes bitmap peuvent être utilisées directement sur les clés de type chaîne, et les clés actionnées par des commandes bitmap peuvent également être utilisées par des commandes de type chaîne.

Par exemple, il existe une clé de chaîne foo :

redis> set foo bar

1 octet est constitué de 8 bits binaires, donc la forme binaire de la clé foo est :

Une analyse approfondie des bitmaps dans Redis (bitmap)

SETBIT

Grâce à la commande SETBIT, La valeur de réglage du bit binaire au niveau du décalage peut être spécifiée pour le décalage du bitmap qui doit être supérieur ou égal à 0 et la valeur ne peut être que 0 ou 1. La complexité temporelle de cette commande est O(1).

Valeur de décalage de la clé SETBITSETBIT key offset value

SETBIT 命令在对二进制位进行设置之后,将返回二进制位被设置之前的旧值作为结果。

假设现在想把 bar 变为 aar,只需如下两步操作:

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 一共有 16 个二进制位,并不是 10 个,且 11~15 的二进制位也是 0。

基于这种情况,当指定的二进制位偏移量过大时,Redis 需要一次性分配完所有内存,这可能会造成 Redis 服务器阻塞。比如存储用户的性别,1 代表男性,0 代表女性,使用 ID 作为二进制偏移量,如果 ID 从 10000000001 开始的,就需要将用户 ID 减去 10000000000 再进行存储,否则会造成内存浪费。

GETBIT

使用 GETBIT 命令可以获取位图指定偏移量上的二进制位的值。此命令的时间复杂度是 O(1)。

GETBIT key offset

如果输入的偏移量超过了位图目前拥有的最大偏移量,将返回 0 作为结果。

BITCOUNT

通过 BITCOUNT 命令可以统计位图中值为 1 的二进制位数量。此命令的时间复杂度是 O(n)。

BITCOUNT key [start end]

在默认情况下,BITCOUNT 命令对位图包含的所有字节中的二进制位进行统计,也可以通过可选的 start 参数和 end 参数,让 BITCOUNT 只对指定字节范围内的二进制位进行统计(不是二进制偏移量)。比如,希望统计 ar 两个字节中值为 1 的二进制数量:

redis> bitcount foo 1 2
(integer) 7

start 和 end 参数也支持使用负数索引,下方的用法与上方的等效:

redis> bitcount foo -2 -1
(integer) 7

BITPOS

通过执行 BITPOS 命令,在位图中查找第一个被设置为指定值的二进制位,并返回这个二进制位的偏移量。

BITPOS key value [start end]

BITPOS 也接受可选的 start 参数和 end 参数,让 BITPOS 命令只在指定字节范围内的二进制位中进行查找。

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 作为结果

BITOP

通过 BITOP 命令,对一个或多个位图执行指定的二进制位运算,并将运算结果存储到指定的键中。

BITOP operation destkey key [key ...]

Après avoir défini le bit binaire, la commande SETBIT renverra l'ancienne valeur avant que le bit binaire ne soit défini comme résultat. 🎜🎜Supposons que vous souhaitiez maintenant changer bar en aar, vous n'avez besoin que des deux étapes suivantes : 🎜
redis> set foo1 bar
OK
redis> set foo2 aar
OK
redis> bitop or res foo1 foo2
(integer) 3
redis> get res"car"
🎜Lors de l'exécution de la commande SETBIT pour essayer de définir un bitmap, si le bitmap n'existe pas ou si la taille actuelle du bitmap ne peut pas Pour être satisfait, Redis étendra le bitmap défini et initialisera les valeurs de tous les bits binaires non définis à 0. Par exemple : 🎜rrreee🎜Puisque far n'existe pas, Redis définira les bits binaires de 0 à 9 à 0. Parce que Redis étend le bitmap en octets, il y a en fait 16 fars au total. Il n'y a pas 10 chiffres binaires, et le. les chiffres binaires de 11 à 15 valent également 0. 🎜
🎜Sur la base de cette situation, lorsque le décalage de bits binaires spécifié est trop grand, Redis doit allouer toute la mémoire en même temps, ce qui peut entraîner le blocage du serveur Redis. Par exemple, lors du stockage du sexe de l'utilisateur, 1 représente un homme et 0 représente une femme, en utilisant l'ID comme décalage binaire. Si l'ID commence à 1 000 000 0001, vous devez soustraire 1 000 000 000 de l'ID utilisateur avant de le stocker, sinon cela entraînera une perte de données. mémoire. 🎜

🎜🎜GETBIT🎜🎜🎜🎜Utilisez la commande GETBIT pour obtenir la valeur du bit binaire au décalage spécifié du bitmap. La complexité temporelle de cette commande est O(1). 🎜🎜Décalage de clé GETBIT🎜🎜Si le décalage d'entrée dépasse le décalage maximum actuellement détenu par le bitmap, 0 sera renvoyé comme résultat. 🎜

🎜🎜BITCOUNT🎜🎜🎜🎜La commande BITCOUNT peut être utilisée pour compter le nombre de bits binaires avec une valeur de 1 dans le bitmap. La complexité temporelle de cette commande est O(n). 🎜🎜Touche BITCOUNT [start end]🎜🎜Par défaut, la commande BITCOUNT compte les bits binaires dans tous les octets contenus dans le bitmap. Elle peut également transmettre le paramètre facultatif de début et le paramètre de fin, soit BITCOUNT. ne compte que les bits binaires dans la plage 🎜octet🎜 spécifiée (pas les décalages binaires). Par exemple, vous souhaitez compter le nombre de nombres binaires avec une valeur de 1 dans les deux octets de ar : 🎜rrreee🎜Les paramètres de début et de fin prennent également en charge l'utilisation d'index négatifs. L'utilisation ci-dessous est équivalente à celle ci-dessus : 🎜. rrreee

🎜🎜BITPOS🎜🎜🎜🎜En exécutant la commande BITPOS, recherchez le premier bit binaire défini sur la valeur spécifiée dans le bitmap et renvoyez le décalage de ce bit binaire. 🎜🎜Valeur de la clé BITPOS [start end]🎜🎜BITPOS accepte également les paramètres de début et de fin facultatifs, permettant à la commande BITPOS de rechercher uniquement dans les bits binaires dans la plage 🎜byte🎜 spécifiée. 🎜rrreee🎜Traitement des limites : 🎜
  • Lorsque vous essayez de trouver un bit binaire avec une valeur de 1 dans un bitmap qui n'existe pas ou un bitmap avec tous les bits définis sur 0, la commande BITPOS renvoie -1 comme résultat.
  • Si vous recherchez un bit binaire avec une valeur de 0 dans un bitmap où tous les bits sont définis sur 1, la commande BITPOS renverra le décalage maximum du bitmap plus 1 comme résultat
  • 🎜🎜BITOP🎜🎜🎜🎜Utilisez la commande BITOP pour effectuer des opérations binaires spécifiées sur un ou plusieurs bitmaps et stocker les résultats de l'opération dans la clé spécifiée. 🎜🎜Touche de destkey d'opération BITOP [clé ...]🎜

    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"

    Une analyse approfondie des bitmaps dans Redis (bitmap)

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

    应用场景

    用户行为记录器

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

    用户上线统计

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

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

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer