基于Redis实现在线游戏积分排行榜

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,倚天版 1GB 1个月
简介: 个人学习

1. 阿里云瑶池旗下的云数据库Redis版是一个全托管的内存数据库服务,具有低延迟、高吞吐和弹性扩缩容的特点。基于高可靠的双机热备架构和可平滑扩展的集群架构,可以满足高读写性能场景和弹性变配的业务需求。

2. 使用云数据库Redis版制作游戏积分排行榜的感受:

(1) 低延迟和高性能,可以快速记录和读取用户积分数据,及时更新排行榜,给用户很好的体验。

(2) 弹性扩容,可以根据用户量增长迅速调整Redis集群配置,扩大存储空间和提高读写性能,避免排行榜查询受限。

(3) 高可靠,双机热备架构可以保证积分数据的安全性,避免数据丢失对用户排名的影响。  

3. 实践过程中可能面临的困难和解决方案:

(1) 用户量剧增导致的性能压力,可以通过快速扩容Redis集群节点来解决。  

(2) 用户量远超预期,数据量超出单台Redis服务器的存储限制,需要添加Redis分片来解决数据横向扩展的问题。

(3) 热门游戏部分服务器节点访问压力过大,可以通过Redis Cluster来分片存储数据和平衡访问压力。

4. 除游戏排行榜外,云数据库Redis版还可以用于:

(1) 缓存系统:临时存储热点数据,提高查询效率。

(2) 计数器:微博数、评论数等的统计。

(3) 社交网络:好友列表、社交关系等的缓存。

(4) 消息队列:实现异步任务和消息通知。  

(5) 会话管理:登录会话的存储和维护。

云数据库Redis版可以用于广泛的应用场景,尤其适合于要求高性能和高可扩展性的业务系统。除游戏排行榜外,它还非常适合构建缓存系统、社交网络、消息队列等应用。

详细的操作步骤(实践版本)

创建实验资源

Redis和ecs对于新用户是免费的,但是对于老用户是收费的,我这个是用的新的Redis和自建了一个按量付费的ecs,详细的ecs配置信息在实验表格里都写了,我就不重复了

搭建Java环境

```js

yum -y install java-1.8.0-openjdk-devel.x86_64

wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.9.2/binaries/apache-maven-3.9.2-bin.tar.gz

```  

3.6.3被删了好像404找不到了,所以用了最新更新的3.9.2,效果是一样一样的

```js

tar -zxvf apache-maven-3.9.2-bin.tar.gz -C /usr/local/ && mv /usr/local/apache-maven-3.9.2/ /usr/local/maven

echo "export PATH=$PATH:/usr/local/maven/bin" >> /etc/profile

source /etc/profile

vim /usr/local/maven/conf/settings.xml

```  

找到黄色字体的位置,加入黄色字体的字符,如果有报错全删了把下边直接复制过去

![image.png](https://ucc.alicdn.com/pic/developer-ecology/be3faq7y2ftbo_9c57ddd1012e4911a9e082cfab522162.png)

```js

<?xml version="1.0" encoding="UTF-8"?>

<!--

Licensed to the Apache Software Foundation (ASF) under one

or more contributor license agreements.  See the NOTICE file

distributed with this work for additional information

regarding copyright ownership.  The ASF licenses this file

to you under the Apache License, Version 2.0 (the

"License"); you may not use this file except in compliance

with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,

software distributed under the License is distributed on an

"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

KIND, either express or implied.  See the License for the

specific language governing permissions and limitations

under the License.

-->

<!--

| This is the configuration file for Maven. It can be specified at two levels:

|

|  1. User Level. This settings.xml file provides configuration for a single user,

|                 and is normally provided in ${user.home}/.m2/settings.xml.

|

|                 NOTE: This location can be overridden with the CLI option:

|

|                 -s /path/to/user/settings.xml

|

|  2. Global Level. This settings.xml file provides configuration for all Maven

|                 users on a machine (assuming they're all using the same Maven

|                 installation). It's normally provided in

|                 ${maven.conf}/settings.xml.

|

|                 NOTE: This location can be overridden with the CLI option:

|

|                 -gs /path/to/global/settings.xml

|

| The sections in this sample file are intended to give you a running start at

| getting the most out of your Maven installation. Where appropriate, the default

| values (values used when the setting is not specified) are provided.

|

|-->

<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">

 <!-- localRepository

  | The path to the local repository maven will use to store artifacts.

  |

  | Default: ${user.home}/.m2/repository

 <localRepository>/path/to/local/repo</localRepository>

 -->

 <!-- interactiveMode

  | This will determine whether maven prompts you when it needs input. If set to false,

  | maven will use a sensible default value, perhaps based on some other setting, for

  | the parameter in question.

  |

  | Default: true

 <interactiveMode>true</interactiveMode>

 -->

 <!-- offline

  | Determines whether maven should attempt to connect to the network when executing a build.

  | This will have an effect on artifact downloads, artifact deployment, and others.

  |

  | Default: false

 <offline>false</offline>

 -->

 <!-- pluginGroups

  | This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.

  | when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers

  | "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.

  |-->

 <pluginGroups>

   <!-- pluginGroup

    | Specifies a further group identifier to use for plugin lookup.

   <pluginGroup>com.your.plugins</pluginGroup>

   -->

 </pluginGroups>

 <!-- TODO Since when can proxies be selected as depicted? -->

 <!-- proxies

  | This is a list of proxies which can be used on this machine to connect to the network.

  | Unless otherwise specified (by system property or command-line switch), the first proxy

  | specification in this list marked as active will be used.

  |-->

 <proxies>

   <!-- proxy

    | Specification for one proxy, to be used in connecting to the network.

    |

   <proxy>

     <id>optional</id>

     <active>true</active>

     <protocol>http</protocol>

     <username>proxyuser</username>

     <password>proxypass</password>

     <host>proxy.host.net</host>

     <port>80</port>

     <nonProxyHosts>local.net|some.host.com</nonProxyHosts>

   </proxy>

   -->

 </proxies>

 <!-- servers

  | This is a list of authentication profiles, keyed by the server-id used within the system.

  | Authentication profiles can be used whenever maven must make a connection to a remote server.

  |-->

 <servers>

   <!-- server

    | Specifies the authentication information to use when connecting to a particular server, identified by

    | a unique name within the system (referred to by the 'id' attribute below).

    |

    | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are

    |       used together.

    |

   <server>

     <id>deploymentRepo</id>

     <username>repouser</username>

     <password>repopwd</password>

   </server>

   -->

   <!-- Another sample, using keys to authenticate.

   <server>

     <id>siteServer</id>

     <privateKey>/path/to/private/key</privateKey>

     <passphrase>optional; leave empty if not used.</passphrase>

   </server>

   -->

 </servers>

 <!-- mirrors

  | This is a list of mirrors to be used in downloading artifacts from remote repositories.

  |

  | It works like this: a POM may declare a repository to use in resolving certain artifacts.

  | However, this repository may have problems with heavy traffic at times, so people have mirrored

  | it to several places.

  |

  | That repository definition will have a unique id, so we can create a mirror reference for that

  | repository, to be used as an alternate download site. The mirror site will be the preferred

  | server for that repository.

  |-->

 <mirrors>

   <!-- mirror

    | Specifies a repository mirror site to use instead of a given repository. The repository that

    | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used

    | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.

    |

   <mirror>

     <id>mirrorId</id>

     <mirrorOf>repositoryId</mirrorOf>

     <name>Human Readable Name for this Mirror.</name>

     <url>http://my.repository.com/repo/path</url>

   </mirror>

   <mirror>

      <id>nexus-aliyun</id>

      <mirrorOf>central</mirrorOf>

      <name>Nexus aliyun</name>

      <url>http://maven.aliyun.com/nexus/content/groups/public</url>

   </mirror>

    -->

   <mirror>

     <id>maven-default-http-blocker</id>

     <mirrorOf>external:http:*</mirrorOf>

     <name>Pseudo repository to mirror external repositories initially using HTTP.</name>

     <url>http://0.0.0.0/</url>

     <blocked>true</blocked>

   </mirror>

 </mirrors>

 <!-- profiles

  | This is a list of profiles which can be activated in a variety of ways, and which can modify

  | the build process. Profiles provided in the settings.xml are intended to provide local machine-

  | specific paths and repository locations which allow the build to work in the local environment.

  |

  | For example, if you have an integration testing plugin - like cactus - that needs to know where

  | your Tomcat instance is installed, you can provide a variable here such that the variable is

  | dereferenced during the build process to configure the cactus plugin.

  |

  | As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles

  | section of this document (settings.xml) - will be discussed later. Another way essentially

  | relies on the detection of a property, either matching a particular value for the property,

  | or merely testing its existence. Profiles can also be activated by JDK version prefix, where a

  | value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'.

  | Finally, the list of active profiles can be specified directly from the command line.

  |

  | NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact

  |       repositories, plugin repositories, and free-form properties to be used as configuration

  |       variables for plugins in the POM.

  |

  |-->

 <profiles>

   <!-- profile

    | Specifies a set of introductions to the build process, to be activated using one or more of the

    | mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/>

    | or the command line, profiles have to have an ID that is unique.

    |

    | An encouraged best practice for profile identification is to use a consistent naming convention

    | for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc.

    | This will make it more intuitive to understand what the set of introduced profiles is attempting

    | to accomplish, particularly when you only have a list of profile id's for debug.

    |

    | This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo.

   <profile>

     <id>jdk-1.4</id>

     <activation>

       <jdk>1.4</jdk>

     </activation>

     <repositories>

       <repository>

         <id>jdk14</id>

         <name>Repository for JDK 1.4 builds</name>

         <url>http://www.myhost.com/maven/jdk14</url>

         <layout>default</layout>

         <snapshotPolicy>always</snapshotPolicy>

       </repository>

     </repositories>

   </profile>

   -->

   <!--

    | Here is another profile, activated by the property 'target-env' with a value of 'dev', which

    | provides a specific path to the Tomcat instance. To use this, your plugin configuration might

    | hypothetically look like:

    |

    | ...

    | <plugin>

    |   <groupId>org.myco.myplugins</groupId>

    |   <artifactId>myplugin</artifactId>

    |

    |   <configuration>

    |     <tomcatLocation>${tomcatPath}</tomcatLocation>

    |   </configuration>

    | </plugin>

    | ...

    |

    | NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to

    |       anything, you could just leave off the <value/> inside the activation-property.

    |

   <profile>

     <id>env-dev</id>

     <activation>

       <property>

         <name>target-env</name>

         <value>dev</value>

       </property>

     </activation>

     <properties>

       <tomcatPath>/path/to/tomcat/instance</tomcatPath>

     </properties>

   </profile>

   -->

 </profiles>

 <!-- activeProfiles

  | List of profiles that are active for all builds.

  |

 <activeProfiles>

   <activeProfile>alwaysActiveProfile</activeProfile>

   <activeProfile>anotherAlwaysActiveProfile</activeProfile>

 </activeProfiles>

 -->

</settings>

```  

开发游戏玩家积分排行榜功能

```js

mkdir -p demo/src/main/java/test/ && cd demo

```  

注意此处不要用vim用vi粘贴防止格式变化

```js

vi src/main/java/test/GameRankSample.java

```  

![image.png](https://ucc.alicdn.com/pic/developer-ecology/be3faq7y2ftbo_c5ce89f619cb40ce9a766a754992d0ac.png)

```js

package test;

import java.util.ArrayList;

import java.util.List;

import java.util.Set;

import java.util.UUID;

import redis.clients.jedis.Jedis;

import redis.clients.jedis.Tuple;

public class GameRankSample {

   static int TOTAL_SIZE = 20;

   public static void main(String[] args)  

   {

       //Redis数据库连接地址

       String host = "r-*********44g9i5m63v.redis.rds.aliyuncs.com";

       //连接密码

       String password = "Wine@123456789";

       int port = 6379;

       Jedis jedis = new Jedis(host, port);

       try {

           String authString = jedis.auth(password);

           if (!authString.equals("OK"))

           {

               System.err.println("AUTH Failed: " + authString);

               return;

           }

           //Key(键)

           String key = "游戏名:奔跑吧,阿里!";

           //清除可能的已有数据

           jedis.del(key);

           //模拟生成若干个游戏玩家

           List<String> playerList = new ArrayList<String>();

           for (int i = 0; i < TOTAL_SIZE; ++i)

           {

               //随机生成每个玩家的ID

               playerList.add(UUID.randomUUID().toString());

           }

           System.out.println("输入所有玩家 ");

           //记录每个玩家的得分

           for (int i = 0; i < playerList.size(); i++)

           {

               //随机生成数字,模拟玩家的游戏得分

               int score = (int)(Math.random()*5000);

               String member = playerList.get(i);

               System.out.println("玩家ID:" + member + ", 玩家得分: " + score);

               //将玩家的ID和得分,都加到对应key的SortedSet中去

               jedis.zadd(key, score, member);

           }

           //输出打印全部玩家排行榜

           System.out.println();

           System.out.println("       "+key);

           System.out.println("       全部玩家排行榜                    ");

           //从对应key的SortedSet中获取已经排好序的玩家列表

           Set<Tuple> scoreList = jedis.zrevrangeWithScores(key, 0, -1);

           for (Tuple item : scoreList) {  

               System.out.println("玩家ID:"+item.getElement()+", 玩家得分:"+Double.valueOf(item.getScore()).intValue());

           }  

           //输出打印Top5玩家排行榜

           System.out.println();

           System.out.println("       "+key);

           System.out.println("       Top 玩家");

           scoreList = jedis.zrevrangeWithScores(key, 0, 4);

           for (Tuple item : scoreList) {  

               System.out.println("玩家ID:"+item.getElement()+", 玩家得分:"+Double.valueOf(item.getScore()).intValue());

           }

           //输出打印特定玩家列表

           System.out.println();

           System.out.println("         "+key);

           System.out.println("          积分在1000至2000的玩家");

           //从对应key的SortedSet中获取已经积分在1000至2000的玩家列表

           scoreList = jedis.zrangeByScoreWithScores(key, 1000, 2000);

           for (Tuple item : scoreList) {  

               System.out.println("玩家ID:"+item.getElement()+", 玩家得分:"+Double.valueOf(item.getScore()).intValue());

           }  

       } catch (Exception e) {

           e.printStackTrace();

       }finally{

           jedis.quit();

           jedis.close();

       }

   }

}

  13  vim pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

   <modelVersion>4.0.0</modelVersion>

   <groupId>test</groupId>

   <artifactId>demo</artifactId>

   <version>0.0.1-SNAPSHOT</version>

   <name>demo</name>

   <description>Demo project</description>

   <properties>

       <java.version>1.8</java.version>

   </properties>

   <dependencies>

       <dependency>

           <groupId>redis.clients</groupId>

           <artifactId>jedis</artifactId>

           <version>2.9.0</version>

       </dependency>

   </dependencies>

   <build>

       <plugins>

           <plugin>

               <artifactId>maven-assembly-plugin</artifactId>

               <configuration>

                   <appendAssemblyId>false</appendAssemblyId>

                   <descriptorRefs>

                       <descriptorRef>jar-with-dependencies</descriptorRef>

                   </descriptorRefs>

                   <archive>

                       <manifest>

                           <!--jar入口类,格式Package.ClassName -->

                           <mainClass>test.GameRankSample</mainClass>

                       </manifest>

                   </archive>

               </configuration>

               <executions>

                   <execution>

                       <id>make-assembly</id>

                       <phase>package</phase>

                       <goals>

                           <goal>assembly</goal>

                       </goals>

                   </execution>

               </executions>

           </plugin>

       </plugins>

   </build>

</project>

```  

打包执行

```js

mvn clean package assembly:single -DskipTests

java -classpath target/demo-0.0.1-SNAPSHOT.jar test.GameRankSample

```  

![image.png](https://ucc.alicdn.com/pic/developer-ecology/be3faq7y2ftbo_6dca1074cf0047d5aa99b233525ae16c.png)

 

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
11月前
|
弹性计算 NoSQL Redis
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
388 0
|
存储 SQL 缓存
SpringBoot集成Redis业务功能 01、限制玩家积分的每日重置次数
SpringBoot集成Redis业务功能 01、限制玩家积分的每日重置次数
SpringBoot集成Redis业务功能 01、限制玩家积分的每日重置次数
|
SQL 存储 NoSQL
使用Redis实现用户积分及TopN排行榜功能
需求:添加积分 在用户签到的基础上添加用户积分,签到 1 天送 10 积分,连续签到 2 天送 20 积分,3 天送 30 积分,4 天以上均送 50 积分。 积分排行榜
408 0
使用Redis实现用户积分及TopN排行榜功能
|
XML NoSQL Java
基于Redis实现在线游戏积分排行榜-2
基于Redis实现在线游戏积分排行榜-2
179 0
|
NoSQL Java Maven
基于Redis实现在线游戏积分排行榜-1
基于Redis实现在线游戏积分排行榜-1
199 0
|
存储 弹性计算 NoSQL
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
基于Redis实现在线游戏积分排行榜
|
4天前
|
NoSQL 数据可视化 Redis
Mac安装Redis
Mac安装Redis
14 3
|
4天前
|
NoSQL Ubuntu 安全
在Ubuntu 18.04上安装和保护Redis的方法
在Ubuntu 18.04上安装和保护Redis的方法
14 0
|
5天前
|
存储 NoSQL Java
使用redis进行手机验证码的验证、每天只能发送三次验证码 (redis安装在虚拟机linux系统中)
该博客文章展示了如何在Linux虚拟机上使用Redis和Jedis客户端实现手机验证码的验证功能,包括验证码的生成、存储、验证以及限制每天发送次数的逻辑,并提供了测试结果截图。
使用redis进行手机验证码的验证、每天只能发送三次验证码 (redis安装在虚拟机linux系统中)
|
5天前
|
NoSQL Linux 网络安全
Linux系统安装Redis
该博客文章详细介绍了在Linux系统中安装Redis的步骤,包括下载、编译、配置、启动Redis服务以及使用客户端访问Redis数据库的过程。
Linux系统安装Redis