In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article focuses on "how to use Redis bitmap operation gracefully". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor learn how to use Redis bitmap gracefully.
Before moving on to today's topic, let's briefly explain what the bitmap in Redis is. The official Redis documentation describes bitmaps as follows:
A bitmap is not a real data type, but a collection of bit-oriented operations defined on a string type. Because the string type is a binary-safe binary large object, and the maximum length is 512MB, it is suitable to set 2 ^ 32 different bits.
Bit operations are divided into two groups: constant-time single-bit operations, such as setting a bit to 1 or 0, or getting the value of that bit. An operation on a set of bits, such as calculating the number of bits in a specified range.
The biggest advantage of bitmaps is that it is sometimes a very significant way to save space to store information. For example, in a system where different users are represented by an incremental user ID, the memory of 512MB can be used to represent the individual bit information of 4 million users (such as whether they need to receive letters).
In short, bitmap operations are used to manipulate bits, which have the advantage of saving memory space. Why can you save memory space? If we need to store the login status of 1 million users, we only need at least 1 million bits to use the bitmap (bit 1 means login, bit 0 means not logged in), and if it is stored in the form of a string, such as userId as key, whether to log in (string "1" means login, string "0" means not logged in) is stored for value You need to store 1 million strings, which takes up much less space than using bitmap storage, which is the advantage of bitmap storage.
Common operation of bitmap
Common operations for bitmaps are as follows:
Setbit
Sets the value of the bit corresponding to a specific key.
Getbit
Gets the value of the bit corresponding to a specific key.
Bitcount
Counts the number of string bits that correspond to a given key.
Use bitmaps to store user login status
A common use of bitmaps is to store state values, such as the login status of users.
Suppose we have a requirement that we need to record the login status of the user every day since registration, then we can take the user id as the key, and then store the login status in the corresponding bit with the date or date offset as the subscript, so that we can easily get the login status of the user on a certain day.
Let's take a look at the code:
Public class UserLoginStatusService {private static final String host= "111.111.111.111"; private static final int port=6379; private static final Jedis jedis=new Jedis (host,port); / / the initial value of the date (which can also be understood as the user's registration time), / / below you need to use the offset of the date as the offset of the redis bitmap, / / so you need to subtract the initial date from the date on which the login status will be saved. / the new date API private static final LocalDate beginDate=LocalDate.of of Java 8 is used here; static {jedis.connect ();} public void setLoginStatus (String userId,LocalDate date,boolean isLogin) {long offset = getDateDuration (beginDate, date); jedis.setbit (userId,offset,isLogin);} public boolean getLoginStatus (String userId,LocalDate date) {long offset = getDateDuration (beginDate, date) Return jedis.getbit (userId,offset);} private long getDateDuration (LocalDate start, LocalDate end) {return start.until (end, ChronoUnit.DAYS);} public static void main (String [] args) {UserLoginStatusService userLoginStatusService=new UserLoginStatusService (); String userId= "user_1"; LocalDate today = LocalDate.now (); userLoginStatusService.setLoginStatus (userId,today,true) Boolean todayLoginStatus = userLoginStatusService.getLoginStatus (userId,today); System.out.println (String.format ("The loginStatus of% s in% s is% s", userId,today,todayLoginStatus)); LocalDate yesterday = LocalDate.now (). MinusDays (1); boolean yesterdayLoginStatus = userLoginStatusService.getLoginStatus (userId,yesterday); System.out.println (String.format ("The loginStatus of% s in% s is% s", userId,yesterday,yesterdayLoginStatus));}}
The code is not complicated. We set the login status of the day to true in the main method, and then find out the login status of the day and the login status of yesterday, respectively. Since the bit of the redis bitmap defaults to 0, the correct output of the code should be logged in today and not logged in yesterday. Let's run it again to see the result.
From the running results of the program, the bitmap of Redis does meet our needs, and it also has the advantage of saving storage space.
Use bitmap to count login days
Next, we have a new requirement, that is, to count the login days of a user in the first 10 days after registration. There is a bitcount command in Redis, which can count the number of bits in a string as 1. It also has two parameters start and end, indicating the range to be counted. At first glance, it seems that it can be used to achieve this requirement, but there is a pit to note here. The start and end parameters of the bitcount command refer to the index of bytes. Instead of the bit index, if we want to use a bitmap to count the login days of a user in the first 10 days after registration, we need to count the number of bits with a value of 1 from 0 to 9, so it is obviously impossible to use the bitcount command directly. So what if we have to use bitmaps to store login status? In fact, there is still a way. We can first get the byte array in which the bit index is from 0 to 9, and then parse the byte array into binary form, and then count the number of bit indexes from 0 to 9 with a value of 1.
To get the subscript of the byte in the byte array, simply divide the bit index by 8 (a byte contains 8 bits) and round it down. The next step is to use redis's getrange command to intercept the byte array.
After getting the byte array, the next step is to parse the byte array and count the number of bits with a value of 1. Let's start with the simplest single byte, assuming that the values of each bit of a byte are as follows:
We set the bit index to index. If we want to calculate the bit value of bit 7, we just need to sum the original value directly with 1. To calculate a bit value with a bit of 6, simply move the original value 1 bit to the right, and then operate with 1. And so on, to calculate the bit value of the index bit, you just need to move the (7-index) bit to the right, and then do the and operation with 1.
As long as it is possible to count the number of bits with a value of 1 in the intercepted byte array, and then subtract the number of bits with a value of 1 that is not included in the corresponding bit index, the number of bits with a value of 1 in a given range of bits can be counted.
This is a bit of a mouthful. Let's take the above example as an example. We need to count the number of login days in the first 10 days after user registration. if the user's login status is stored in a bitmap and the index in the bitmap is the number of days of registration, then we need to count the number of bits with a value of 1 from 0 to 9 in order to calculate the login days of the user in the first 10 days after registration.
We first calculate which byte array the bit index is contained in from 0 to 9. As mentioned earlier, you just need to divide the corresponding index by 8 and round it down. Thus, we can know that the bit index from 0 to 9 corresponds to a byte array with subscript from 0 to 1.
Next, use the getrange command to intercept the byte array, assuming that its value is as follows:
Assuming that the bit values of the byte array corresponding to bit indexes 0 to 9 are as shown above, what we need to count is the number of bits with a value of 1 in bits 0 to 7 in the first byte (subscript 0). Plus the number of bits with a value of 1 in bits 0 to 1 in the second byte (subscript 1). It adds up to just 10 digits, that is, the number of login days before the corresponding user registers. Of course, we can also count the total number of bits with a value of 1 in these two bytes, and then subtract the number of bits with a value of 1 in the second byte from 2 to 7 bits (where the table is red above). You can also count the login days of the user in the first 10 days after registration. The second method is used in this paper.
Next, add the code:
Private static final int BIT_AMOUNT_IN_ONE_BYTE = 8; private Jedis jedis; public int bitCountByBitIndex (String key, long startBitIndex, long endBitIndex) {int startByteIndex = getByteIndexInTheBytes (startBitIndex); int endByteIndex = getByteIndexInTheBytes (endBitIndex); byte [] bytes = jedis.getrange (key.getBytes (), startByteIndex, endByteIndex); int totalBitInBytes = getTotalBitInBytes (bytes); int startBitIndexInFirstByte = getBitIndexInTheByte (startBitIndex); int endBitIndexInLastByte = getBitIndexInTheByte (endBitIndex) Byte firstByte = bytes [0]; byte lastByte = bytes [bytes.length-1]; for (int iTunes 7 for > (BIT_AMOUNT_IN_ONE_BYTE-1-startBitIndexInFirstByte); iMurray -) {if (firstByte > > I) & 1) = = 1) {totalBitInBytes--;}} for (int ibis 0 for I > I) & 1) = 1) {totalBitInBytes-- }} return totalBitInBytes;} private int getTotalBitInBytes (byte [] bytes) {int count=0; for (byte b:bytes) {for (int I = 0; I)
< BIT_AMOUNT_IN_ONE_BYTE; i++){ if(((b>> I) & 1) = 1) {count++;} return count;} private int getByteIndexInTheBytes (long offset) {return (int) offset/ BIT_AMOUNT_IN_ONE_BYTE } private int getBitIndexInTheByte (long offset) {return (int) (offset-offset/ BIT_AMOUNT_IN_ONE_BYTE * BIT_AMOUNT_IN_ONE_BYTE);}
The code will not be commented, and the overall idea has been explained above.
Of course, in order to achieve the functions described in this article, it is not necessary to do so, there are other solutions. For example, the offset put into the bitmap can be uniformly multiplied by 8 (8 bits per byte), so that you can directly use the bitcount of redis to count the number of bits with a value of 1 in the corresponding index range. Of course, the disadvantage of this scheme is quite obvious, that is, it is a waste of memory, because previously only 1 bit of data is needed, now 8 bits of storage is needed. Therefore, this scheme can not make good use of the characteristics of bitmap index to save storage space.
At this point, I believe you have a deeper understanding of "how to use Redis bitmap operation gracefully". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.