I make a web site LmssPlus that allows to look up League game personal information, there is a very sweet part (for me) that the player wants to know how much proficiency score they are using is in the whole VN server. .
Let me explain a little to those of you who don’t play League. In general, you will have many different generals to choose from a total of 150 generals, but people instead of playing all 150 generals, they usually only play about a dozen, and up to about 30 generals is a lot. . Each time you play that hero, you will gain more proficiency points.
So the needs of users here:
- They want to know how much proficient General X they play in the server.
- They wanted to know the top players who were most proficient at General X’s server.
My first thought was quite simple, I used Mongodb, first the model
1 2 3 4 5 6 | <span class="token keyword">var</span> chema <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">mongoose <span class="token punctuation">.</span> Schema</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> accountId <span class="token operator">:</span> Number <span class="token punctuation">,</span> <span class="token comment">//người chơi</span> championId <span class="token operator">:</span> Number <span class="token punctuation">,</span> <span class="token comment">//tướng</span> point <span class="token operator">:</span> Number <span class="token punctuation">,</span> <span class="token comment">//điểm thông thạo</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
- Index {accountId: 1, championId: 1} to upsert data (when the user changes proficiency score).
- Index {championId: 1, point: 1} to get rank.
The rank query looks like this:
1 2 | Ssrank <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> championId <span class="token punctuation">,</span> point <span class="token operator">:</span> <span class="token punctuation">{</span> $gt <span class="token operator">:</span> point <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">count</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> |
So championId’s rank is simply the result above plus 1.
We need to take the rankings of all their champions to play, and then display the highest ranked champion, like I am the top 731 Katarina.
So the query would look like this:
For each user who enters, we take about 10-30 queries, the result rate is about 300-500ms, the result of our server is in this situation:
Data will be updated day and night (there is a cron in charge of getting information and updating into db) and when the user goes to the web (for the latest data)
Hmm, after reading a few more blogs, I decided to use Redis with its super-fast advantages, and the amount of ram used is only equivalent to mongodb (1)
First, I write a function to bring data from mongodb to redis, on the mongodb side, I remove the ssranks
collection to save ssranks
ram on the index, instead the hero data will be saved to 1 field champions
in the collection accounts
.
Key
will be cp_id_id, score
will be the proficiency score, and the value
be accountId
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token comment">//khi upsert</span> redis <span class="token punctuation">.</span> <span class="token function">zadd</span> <span class="token punctuation">(</span> <span class="token string">"cp_"</span> <span class="token operator">+</span> championId <span class="token punctuation">,</span> point <span class="token punctuation">,</span> accountId <span class="token punctuation">)</span> <span class="token comment">//truy vấn lấy thứ hạng của tất cả các con tướng của họ chơi</span> <span class="token keyword">await</span> Promise <span class="token punctuation">.</span> <span class="token function">all</span> <span class="token punctuation">(</span> champions <span class="token punctuation">.</span> <span class="token function">map</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token parameter"><span class="token punctuation">{</span> championId <span class="token punctuation">,</span> point <span class="token punctuation">}</span></span> <span class="token punctuation">)</span> <span class="token operator">=></span> redis <span class="token punctuation">.</span> <span class="token function">zrevrank</span> <span class="token punctuation">(</span> <span class="token string">"cp_"</span> <span class="token operator">+</span> championId <span class="token punctuation">,</span> accountId <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token parameter">rank</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> championId <span class="token punctuation">,</span> rank <span class="token operator">:</span> rank <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">,</span> point <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment">//à lấy top 10 người chơi có thông thạo đứng đầu server của tướng thì như này</span> <span class="token keyword">let</span> toprank <span class="token operator">=</span> <span class="token keyword">await</span> redis <span class="token punctuation">.</span> <span class="token function">zrevrange</span> <span class="token punctuation">(</span> <span class="token string">"cp_"</span> <span class="token operator">+</span> championId <span class="token punctuation">,</span> <span class="token number">0</span> <span class="token punctuation">,</span> <span class="token number">9</span> <span class="token punctuation">,</span> <span class="token string">"WITHSCORES"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
And results
- 30ms speed
- Cpu reduced, stable at 5%
Above is what I do, my understanding is limited, so there are any mistakes I hope you to forgive. Thanks!
Ref: