当前位置 : 主页 > 编程语言 > python >

Redis支持二进制案例

来源:互联网 收集:自由互联 发布时间:2022-06-15
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 的排序功能,我们当做跨服的排行榜使用。

看下我们的服务器架构:

Redis支持二进制案例_ide

注:

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、数据存储

数据的存储比较简单,常规的使用就行

@Component
public class RedisUtil {

public static RedisUtil util;

public RedisUtil(@Autowired JedisPool jedisPool) {
this.jedisPool = jedisPool;
RedisUtil.util = this;
}

public static RedisUtil getInstance(){
return util;
}


@Autowired
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、发布订阅

@Component
public class JedisPubListener extends JedisPubSub implements ApplicationRunner {

@Override
public void onMessage(String channel, String message) {
System.out.println(String.format("receive redis published message, channel %s, message %s", channel, message));
}

@Override
public void onSubscribe(String channel, int subscribedChannels) {
System.out.println(String.format("subscribe redis channel success, channel %s, subscribedChannels %d",
channel, subscribedChannels));
}

@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
System.out.println(String.format("unsubscribe redis channel, channel %s, subscribedChannels %d",
channel, subscribedChannels));

}

@Override
public void run(ApplicationArguments args) throws Exception {

}
}
复制代码

因为Jedis的订阅是阻塞的,所以单独开一个线程

@Component
public class ListenerThread extends Thread{
@Autowired
public JedisPubListener listener;
@Autowired
private JedisPool jedisPool;
@PostConstruct
public void init(){
this.start();
System.err.println("thread start");
}
@Override
public void run() {
Jedis resource = jedisPool.getResource();
resource.subscribe(listener,"test");
}
}


作者:香菜聊游戏

链接:https://juejin.cn/post/7086640115845431327

来源:稀土掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

【本文由:阿里云代理 http://www.56aliyun.com 复制请保留原URL】
上一篇:Django数据返回自定义
下一篇:没有了
网友评论