At present, I am writing a project with GO, and I wrote the interface of “like” of this project, which uses Redis for cache and mysql for persistence. However, the project encountered some difficult problems, namely how to persist the liked data gracefully.

Get go-Redis-related dependencies

go get github.com/go-redis/redis/v8

We started with redis for caching and mysql for persistence. This may be more optimized for direct reads from mysql, but it still doesn’t seem to be optimal.

In redis, the key type is set. The ID of a comment corresponds to a key, and the username of the user corresponds to a value. A comment can be liked by many users, but those users have to be different, so the model works.

However, if users frantically like and unlike, it can actually lead to performance degradation. What to do? Obviously, we should not store and delete the like data in mysql in real time. Instead, we can use scheduled tasks to persist part of the like data in Redis in a certain period of time. It’s also easy to think of. However, the data in our Redis will obviously increase over time, and the memory will also be insufficient. Therefore, we need to expire the data in Redis, because some of the “like” data stored in Redis may not be accessed for a long time. In this case, expiration processing can be carried out.

Redis has three expired key deletion strategies:

1. Delete periodically. When setting the expiration time of a key, create a timer to delete the key immediately when the expiration time of the key comes.

2. Lazy deletion. Let the key expire, but each time a key is retrieved from the key space, the key is checked to see if it is expired, and if it is, the key is removed, otherwise the key is returned.

3. Delete regularly. Periodic deletion is a synthesis of the previous two points, that is, set a periodic task, periodic check whether some keys in Redis expired, if expired, delete.

Obviously, I chose the third strategy. For the same comment, I open two sets, one for read and one for write, which is used for periodic deletion.

  • First, when a user likes a comment, the data is stored in the set key for Comment + Comment_id + R, an expiration date is set for each read key, and the same data is stored in the set key for Comment + Comment_id + W.

  • When a user unlikes a comment, the data is first deleted from the read, and if it’s out of date, that’s great, because I’m going to delete it anyway, and if it’s not out of date, then it’s deleted as normal. For data in Wirte, it is either in Redis or persisted. (notice I used for the persistence of the key/value pair is not set the expiration time, because I will be deleted after persistent those data, so there will be no memory unlimited growth) so, I want to determine whether the data in to persistent key-value pairs, if in, it is not persistent, directly from the redis deletes inside, Otherwise, it is persisted, so what we need to do is delete it from mysql.

The above are some of the problems I encountered when writing a “like” interface and the solutions I can think of. I spent about a day thinking about this problem. At present, I think it has been basically solved. At the same time, I have deepened my understanding of Redis while solving problems.