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)