Redis is an open source key-value storage system that provides multiple data types and typically stores all data in memory.


child

Redis is the most popular key-value storage system at present. It is a database based on memory storage OF KV. Rational use of Redis as cache can greatly improve system performance and server request response time.

In addition to basic KV storage, Redis also implements hash (Map), list (list), set (set), sorted set (sorted set) and other data types. Combined with the features of memory and data structure, many features can be flexibly implemented in the process of service function realization.

Today, we introduce ordered collections, which is a data structure. We use ordered collections in actual business processes, and we have gained some valuable experience.

What is an ordered set

In the data types provided by Redis, Sorted Set and Set cannot add duplicate elements to the Set, and only one element with the same value can be added. Ordered collections differ from collections in that they assign each element a score of type double, by which Redis sorts the members of the collection from smallest to largest.


skiplist

In Redis, the ordered set is realized by using a skiplist data structure, which can make the expected time of get, set, Add and remove operations reach O(log N). If you are interested in the specific principle, you can learn by yourself.

Ordered collections provide a wealth of operations that can be applied in many application scenarios.

  • Zunionstore is a union of two ordered sets that can be used to combine the leaderboards of all participants in two polls.
  • Zinterstore is the intersection of two sets, through which you can get a list of candidates voting for multiple candidates at the same time.
  • Zrevrank is a convenient way to query the position of an element in an ordered set, i.e. the ranking of the vote.
  • Zscore is used to query the score of an element in a collection
  • Zrevrank returns the position of an element in a collection
  • Zrevrangebyscore gets a ranking of elements within a score range

Ordered collections provide both small to large and large to small leaderboards, with the command rev returning large to small collections.

Designing voting games

The reason why REDis is selected in the voting game is mainly to consider the support of high concurrency. In the actual application scenario, there may be a high degree of concurrent voting and real-time polling result query during voting. If all operations directly operate the database, it will cause a large load on the database. After reviewing the technical scheme and implementation cost, we decided to adopt the ordered collection provided by Redis to realize the display of voting process and real-time ranking, and directly read the cache to avoid the sudden and high concurrent access of non-core business to the database.

User stories for voting games

  1. Create candidates for the vote
  2. Create a user
  3. Users participate in activities and get a certain amount of voting quota
  4. Users use the voting quota to vote for candidates
  5. Candidates look at the vote count rankings of the users who voted for them
  6. All of you are looking at real-time candidate vote rankings

The game process


vote

First, there can be administrators, creating candidates and users, or candidates and users can register themselves, depending on the needs of the specific scenario. The demo provides interfaces for users and candidates to register themselves. To store user and candidate information, the simplest implementation can use the redis string type key/value, which is itself a hash, or the hash type provided by Redis.

After the user is created, assigning voting quota to the user is the work to be done, through redis string type, INCR implementation, can ensure the atomicity of the operation. The voting process also subtracts some value from this data structure, but in order to prevent concurrent cases where users use more than they own, a lock needs to be designed, and the DECR operation can only be performed once the lock is obtained.

After deducting the user’s quota from the vote, the core data structure can be manipulated to order the collection. The first step is to increase the number of votes received for a particular candidate. This is an ordered set of all candidates’ ids as keys, and the score is the total number of votes received. At the same time, the ranking of each user voting for the same candidate is also recorded on the user’s voting record for this candidate.

Once you’ve done the above, getting real-time poll rankings is a breeze. Ordered collections provide operations that make it easy to query lists related to various rankings.

The code implements the redis call

After designing the game process, you can start to directly implement it. The following uses redis- CLI command to show the whole process of guessing in the form of pseudo-code, and you can view the effect directly under the Redis client.

Redis – cli pseudo code

  1. Create users and campaign candidates
set voter:1 0
set voter:2 0
set voter:3 0

set elector:1 name
set elector:2 name
Copy the code
  1. Allocate quotas to users
incrby voter:1 50
incrby voter:2 40
incrby voter:3 60
Copy the code
  1. Users to vote
# voter:1 # Added total lists zincrby Elector :total: List 25 Elector :1 # added single: Elector :1 25 decrby voter:1 25 # voter:2 zincrby elector:total:list 12 elector:1 zincrby elector:single:elector:1 12 voter:2 decrby voter:2 12 # voter:3 zincrby elector:total:list 40 elector:2 zincrby elector:single:elector:2 40 voter:3 decrby voter:3 40Copy the code
  1. All kinds of list
Zrevrange elector:single:elector:1 0-1 WITHSCORES # Voter :total: Elector 2 Elector :single: Elector :1 elector:single: Elector :2 # Check the rank of user 1 (return subscript starting from 0) zrevrank voter:total:elector voter:1Copy the code

Here is the result:


redis-cli

Node. Js code

Look at the code node.js implementation

Finally, we use Node.js to achieve a simple back-end service demo, javascript data structure and Redis SDK more clearly show the call effect of native commands. Curl curl curl curl curl curl curl curl curl curl

In the implementation process, we can see that if you directly use the command, in fact, the whole voting process only needs a very simple few commands can be completed. The demo demo code, compared with the command, added a lot of interface access and SDK call related code; If the final vote for production application. Write a program, according to the needs of the business logic and capacity planning, and also need to consider more details, software development itself is such a process, starting from a simple ideas and creativity, and then need to consider more realistic scenarios and requirements, constantly in the process of restore the whole idea.