The design idea of thumb up function based on redis is explained in detail

  • 2020-05-27 07:31:01
  • OfStack

preface

Thumb up is actually an interesting feature. There are basically two basic design ideas, one of which is mysql, etc

The database is stored directly on the ground. The other one is to use the business characteristics of thumb up to throw it into redis(or memcache), and then brush it back to mysql offline.

Write Mysql directly

Writing Mysql directly is the easiest thing to do.

Just make two tables,

1. post_like

Record the number of times the article has been liked, how many people have liked this data can be directly looked up from the table;

2, user_like_post

Record which articles have been liked by users. When opening the list of articles, the data showing whether or not the articles have been liked is in it.

disadvantages

1, database reading and writing pressure

Popular articles will have a lot of users thumb up, even in a short time by a large number of thumb up, direct operation of the database from a long view is not very ideal.

The redis store is then batched back to the database

The main feature of redis is that it is fast. After all, most of the data is in memory.

The main reason why I chose redis over memcache is that redis supports more data types, such as hash, set, zset, etc.

These types are used in the details below.

advantages

1. High performance

2. Relieve the pressure of database reading and writing

In fact, I'm more concerned with relieving the writing pressure, the real reading pressure, which can be solved by mysql master and slave and even by adding redis to cache hot data.

Writing pressure is really not good for the previous scheme.

disadvantages

1. Complex development

This is much more complicated than writing mysql directly, and there are many things to consider;

2. Data security cannot be guaranteed

Data will be lost when redis is hung, and data in redis will not be synchronized in time, which may be eliminated when redis memory is replaced.

But for thumb up, it's ok to lose a little bit of data;

The specific design

Mysql design

This block is the same as write mysql, after all, it is to be stored on the ground.

So it's the same thing post_like , user_like_post These two tables store the number of posts that have been thumb up (equal statistics), and the user has liked (unliked) those posts.

The two tables were adopted respectively post_id , user_id Make connections.

redis design section:

post_set

Make one set in redis to store all the articles that are thumb up

post_user_like_set_{$post_id}

For each post, take post_id as key, and make one set to store all users of the post thumb up;

post_user_like_{$post_id}_{$user_id}

Put each user's thumb up for each post into one hash, and the fields of hash are

Feel free to follow up with the demand and deal with it.

Why use hash

hash is only used because it is perfectly possible to use hash to store 1 thumb up object, corresponding to 1 row in the database.

Of course, some students will say key, value is also ok, serialize all the data ( json_encode Etc.)

Put them all in value. Deserialization is also a big overhead. No, hash can be very expensive

Easy to modify a field while serializing and deserializing operations.

user_like_post0

1 counter is maintained for each post to record the current thumb up number in redis,

Here we are using only the number of thumb up (which can be negative) in counter records that have not been synchronized to mysql

When you swipe back to mysql, add the data in counter to the existing likes in the database.

User thumb up/cancel likes

To obtain user_id , post_id , to check whether the user has clicked "like", and if it has clicked "like", thumb up will not be allowed again.

Or design for the front end to allow user points, but the background does not double count;

The important thing to note here is that the user's thumb up record may be in the database or in the cache, so when querying

Both the cache and the database are queried, and the cache does not queried the database.

Record the user's thumb up/cancel like in redis, specifically as follows:

1, write post_set

will post_id write post_set

2, write post_user_like_set_{$post_id}

will user_id write post_user_like_set_{$post_id}

3, write post_user_like_{$post_id}_{$user_id}

Write user thumb up data, such as like status, post_id, user_id, ctime(operation time), mtime(modification time) post_user_like_{$post_id}_{$user_id} In the

4, update, user_like_post0

update user_like_post0 , the update here is a little bit later and complicated. We need to get whether the current user has liked the post as before

If you click, and this time it's cancel like, counter minus 1, if you don't click, this time it's thumb up, counter plus 1.

If the "like" was canceled, this time it is thumb up, counter plus 1.

Sync back to the database

Cycle from post_set One of pop comes out post_id To the empty

According to the {$post_id} Every time, from post_user_like_set_{$post_id} One of pop comes out user_id Until the empty

According to the post_id , user_id , directly get the contents of the corresponding hash table ( post_user_like_{$post_id}_{$user_id}

Writes the data from the hash table user_like_post In the table

will user_like_post0 Data and post_like Add the data in, and write the result to post_like In the table

The page display

1. Query the user's thumb up

As mentioned earlier, you need to query both redis and mysql

2. Query post thumb up for statistics

You also need to query redis user_like_post0 And mysql post_like Table and add them together

The result you get is the correct result

conclusion

The reading and writing problem of mysql has been solved

However, the design of the sub-table is not considered for the scenario with a large number of users. Instead, the sub-table can be considered for user_id or post_id


Related articles: