1、redis 介绍 Redis 是完全开源的,是一个高性能的 key-value 数据库。 redis 的优势 性能高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。 丰富的数据类型 – Redis支持二进制案例的
1、redis 介绍
Redis 是完全开源的,是一个高性能的 key-value 数据库。
redis 的优势
- 性能高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。。
2、在项目中的应用
在游戏服务器中的应用主要有下面几个场景:
基于redis 的高性能,所以我们当做跨服的数据存储使用
基于redis的发布订阅功能,我们当做服务器之间的消息发布使用,统领所有的服务器
基于redis 的排序功能,我们当做跨服的排行榜使用。
看下我们的服务器架构:
注:
MS:跨服服务器
G:游戏逻辑服务器
这里仅仅画出了和redis的链接,并没有标注出游戏的链接
3、代码展示
在项目中加入下面的依赖
<dependency><groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
复制代码
如果你使用springboot搭建的项目,可以加入下面到pom
<dependency><groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
复制代码
1、数据存储
数据的存储比较简单,常规的使用就行
public class RedisUtil {
public static RedisUtil util;
public RedisUtil( JedisPool jedisPool) {
this.jedisPool = jedisPool;
RedisUtil.util = this;
}
public static RedisUtil getInstance(){
return util;
}
private JedisPool jedisPool;
/**
* 向Redis中存值,永久有效
*/
public String set(String key, String value) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
return jedis.set(key, value);
} catch (Exception e) {
return "0";
} finally {
jedis.close();
}
}
/**
* 根据传入Key获取指定Value
*/
public String get(String key) {
Jedis jedis = null;
String value;
try {
jedis = jedisPool.getResource();
value = jedis.get(key);
} catch (Exception e) {
return "0";
} finally {
jedis.close();
}
return value;
}
/**
* 校验Key值是否存在
*/
public Boolean exists(String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
return jedis.exists(key);
} catch (Exception e) {
return false;
} finally {
jedis.close();
}
}
/**
* 删除指定Key-Value
*/
public Long del(String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
return jedis.del(key);
} catch (Exception e) {
return 0L;
} finally {
jedis.close();
}
}
/**
* 分布式锁
* @param key
* @param value
* @param time 锁的超时时间,单位:秒
*
* @return 获取锁成功返回"OK",失败返回null
*/
public String getDistributedLock(String key,String value,int time){
Jedis jedis = null;
String ret = "";
try {
jedis = jedisPool.getResource();
ret = jedis.set(key, value, new SetParams().nx().ex(time));
return ret;
} catch (Exception e) {
return null;
} finally {
jedis.close();
}
}
public void pub(){
jedisPool.getResource().publish("test","msg");
}
}
复制代码
2、排行榜排序功能
排行榜的功能,主要是使用sortset的数据结构,但是这里有一个比较要注意的情况就是时间的问题。
比如相同战力,先上榜的玩家肯定排名靠前,这是毫无疑问的,但是总有些同学会忘记这件事情,
同时,在更新的时候,要把原来值的小数去掉,再加上当前的时间运算之后的值
把玩家id 当做key,把玩家战力当做score,把时间当做小数进行累加
/*** 计算score,通过一个基准时间,可以是2100或2050年,减去lastOrderTime再除以基准时间,可以获得一个小于1的小数,
* 在获取真正score的时候,只要舍去小数位即可
* @param orderNum
* @param lastOrderTime
* @return
*/
private double getOrderNum(int orderNum, long lastOrderTime) {
return orderNum + (BASE_TIME - lastOrderTime) * 1.0 / BASE_TIME;
}
/**
* 向redis中存入数据
* 保存的是经过处理之后的数据
* @param key
* @param value
*/
public long put(String key, int value) {
long time = System.currentTimeMillis();
double dValue = value + 1 - time / Math.pow(10, (int) Math.log10(time) + 1d);
dbData.put(key, dValue);
return time;
}
复制代码
3、发布订阅
public class JedisPubListener extends JedisPubSub implements ApplicationRunner {
public void onMessage(String channel, String message) {
System.out.println(String.format("receive redis published message, channel %s, message %s", channel, message));
}
public void onSubscribe(String channel, int subscribedChannels) {
System.out.println(String.format("subscribe redis channel success, channel %s, subscribedChannels %d",
channel, subscribedChannels));
}
public void onUnsubscribe(String channel, int subscribedChannels) {
System.out.println(String.format("unsubscribe redis channel, channel %s, subscribedChannels %d",
channel, subscribedChannels));
}
public void run(ApplicationArguments args) throws Exception {
}
}
复制代码
因为Jedis的订阅是阻塞的,所以单独开一个线程
public class ListenerThread extends Thread{
public JedisPubListener listener;
private JedisPool jedisPool;
public void init(){
this.start();
System.err.println("thread start");
}
public void run() {
Jedis resource = jedisPool.getResource();
resource.subscribe(listener,"test");
}
}
作者:香菜聊游戏
链接:https://juejin.cn/post/7086640115845431327
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【本文由:阿里云代理 http://www.56aliyun.com 复制请保留原URL】