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_post
0
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_post
0
update
user_like_post
0
, 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_post
0
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_post
0
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