1、Redis的简介
1.1、NoSql
- NoSql 是Not-Only Sql的简写,泛指非关系型数据库
- 关系型数据库不太适合存储非结构化的大数据(现在的非结构化的数据占比90%),所以提出了一个新的数据库解决方案,来存储这样的数据。
- NoSql的分类
- 键值对模型的NoSQL:Tokyo、Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
应用场景:内容缓存,主要用于处理大量数据的高访问负载
优势:快速查询
劣势:存储的数据缺少结构化 - 列式模型的NoSQL:Cassandra, HBase, Riak
应用场景:分布式的文件系统
优势:查找速度快,可扩展性强,更容易进行分布式扩展
劣势:功能相对局限 - 文档模型的NoSQL:CouchDB、MongoDB
应用场景:Web应用
优势:数据结构要求不严格
劣势:查询性能不高,而且缺乏统一的查询语法 - 图模型的NoSQL:Neo4J、InfoGrid、Infinite Graph
应用场景:社交网络
优势:利用图结构相关算法。
劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案。
- 键值对模型的NoSQL:Tokyo、Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
1.2、Redis
Redis是C语言开发的一个开源的高性能(基于内存)的k-v键值对的NO-SQL数据库,提供了丰富的数据类型。
-
字符串类型
-
散列类型(hash)
-
列表类型(list)
-
集合类型(set)
-
有序集合类型(sortedSet)
…
1.3、Redis的发展史
2008年,意大利的一家创业公司Merzia推出了一款基于MySQL的网站实时统计系统LLOOGG,然而没过多久该公司的创始人 Salvatore Sanfilippo便对MySQL的性能感到失望,于是他决定亲自为LLOOGG量身定做一个数据库,并于2009年开发完成,这个数据库就是Redis。不过Salvatore Sanfilippo并不满足只将Redis用于LLOOGG这一款产品,而是希望更多的人使用它,于是在同一年Salvatore Sanfilippo将Redis开源发布,并开始和Redis的另一名主要的代码贡献者Pieter Noordhuis一起继续着Redis的开发,直到今天。
SalvatoreSanfilippo自己也没有想到,短短的几年时间,Redis就拥有了庞大的用户群体。Hacker News在2012年发布了一份数据库的使用情况调查,结果显示有近12%的公司在使用Redis。国内如新浪微博、街旁网、知乎网,国外如GitHub、Stack Overflow、Flickr等都是Redis的用户。
VMware公司从2010年开始赞助Redis的开发,Salvatore Sanfilippo和Pieter Noordhuis也分别在3月和5月加入VMware,全职开发Redis。
1.4、Redis的应用场景
缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用)
分布式集群架构中的session分离。
聊天室的在线好友列表。
任务队列。(秒杀、抢购、12306等等)
应用排行榜。
网站访问统计。
数据过期处理(可以精确到毫秒)
1.5、Redis的特点
redis数据访问速度快(数据在内存中)
redis有数据持久化机制(持久化机制有两种:1、定期将内存数据dump到磁盘;2、aof(append only file)持久化机制——用记日志的方式记录每一条数据更新操作,一旦出现灾难事件,可以通过日志重放来恢复整个数据库)
redis支持集群模式(容量可以线性扩展)
redis相比其他缓存工具(ehcache/memcached),有一个鲜明的优势:支持丰富的数据结构
2、Redis集群的搭建
2.1、下载
官网地址:https://redis.io/
下载地址:http://download.redis.io/releases/redis-4.0.14.tar.gz
2.2、安装环境
Redis安装一般会在Linux系统下进行安装,又因为redis是使用c语言开发,所以需要c语言环境。
Linux:centOS7.7
VMware:14
C语言环境:yum install gcc-c++
2.3、安装步骤
1、上传、解压、更名
2、进入redis执行make命令编译源码
3、安装Redis
make install PREFIX=/usr/local/redis
成功之后可以在指定的目录下生成bin目录
4、配置环境变量
#redis env
export REDIS_HOME=/usr/local/redis
export PATH=$REDIS_HOME/bin:$PATH
5、帮助
redis-cli --help
2.4、Redis的启动
分为前台启动和后台启动
2.4.1前台启动
#启动
redis-server
#关闭
ctrl+C

2.4.2、后台启动
注意: 后台启动需要将解压出来的目录中的redis.conf文件复制到bin目录下,并且修改redis.conf中的dameonize参数为yes(应该在136行)
#启动
redis-server /usr/local/redis/bin/redis.conf
#关闭
redis-cli shutdown
2.3、客户端连接
redis-cli
# 下面是在客户端界面下的一些基础操作
127.0.0.1:6379> set user1 gaoyuanyuan <= 设置一个键值对
OK
127.0.0.1:6379> set user2 linzhiling <= 设置一个键值对
OK
127.0.0.1:6379> get user1 <= 获取键user1的value
"gaoyuanyuan"
127.0.0.1:6379> get user2 <= 获取键user2的value
"linzhiling"
127.0.0.1:6379> keys * <= 查看所有的key
1) "user1"
2) "user2"
可以给server设置密码,主机名,端口,设置之后客户端想要连接server就要输入主机名,端口,密码(在redis.conf中设置)
#设置了主机名,端口,密码
#开启服务端还是redis-server redis-server /usr/local/redis/bin/redis.conf
#关闭服务端
redis-cli -h node01 -a 123123
#客户端连接
redis-cli -h node01 -p 6379 -a 123123
2.4、使用jedis连接客户端
Redis不仅是使用命令来操作,现在基本上主流的语言都有客户端支持,比如java、C、C#、C++、php、Node.js、Go等。
在官方网站里列一些Java的客户端,有Jedis、Redisson、Jredis、JDBC-Redis、等其中官方推荐使用Jedis和Redisson。 在企业中用的最多的就是Jedis,下面我们就重点学习下Jedis。
Jedis同样也是托管在github上,地址:httpsRedis.assets//github.com/xetorthio/jedis
2.4.1、单线程连接
package Day01
/**
* 单线程连接
*/
import redis.clients.jedis.Jedis
object _01JedisDemo {
def main(args: Array[String]): Unit = {
//使用jedis,创建一个redis对象
val jedis = new Jedis("node01", 6379)
//进行密码验证,如果没有设置密码跳过
jedis.auth("123123")
//设置键值对,成功返回OK
jedis.set("name","张作霖")
//追加,如果key存在就覆盖,不存在就追加到其他kv后面
jedis.append("age","22")
//通过k获取v
println(jedis.get("name"),jedis.get("age"))
}
}
2.4.2、线程池连接
package Day01
import java.util
import redis.clients.jedis.{Jedis, JedisPool}
/**
* 连接池连接
*/
object _02JedisPoolDemo {
def main(args: Array[String]): Unit = {
//获取jedis的连接池对象
val pool = new JedisPool("node01", 6379)
//从连接池中获取一个具体的连接 对象
val jedis: Jedis = pool.getResource
//进行密码验证,如果没有设置密码跳过
jedis.auth("123123")
//设置一个kv
jedis.set("gender","男")
jedis.mset("hobby","women","aa","sun")
//获取
val hobby: util.List[String] = jedis.mget("hobby","aa")
//输出
println(hobby)
}
}
3、Redis的数据类型
3.1、字符串类型
3.1.1、命令行操作
#创建一个kv
node01:6379> set name mark
OK
#获取一个k对应的v
node01:6379> get name
"mark"
#创建多个kv
node01:6379> mset name mary age 23 gender f
OK
#获取多个k的v
node01:6379> mget name age gender
1) "mary"
2) "23"
3) "f"
node01:6379> set num 1
OK
#使num自增1(v必须使数字)
node01:6379> incr num
(integer) 2
node01:6379> get num
"2"
#使num自减1(v必须使数字)
node01:6379> decr num
(integer) 1
node01:6379> get num
"1"
#使num自增2(v必须使数字)
node01:6379> incrby num 2
(integer) 3
node01:6379> get num
"3"
#使num自减1(v必须使数字)
node01:6379> decrby num 2
(integer) 1
node01:6379> get num
"1"
3.1.2、jedis操作(scala/java都行)
package Day01
import java.util
import org.apache.commons.pool2.impl.GenericObjectPoolConfig
import redis.clients.jedis.{Jedis, JedisPool}
/**
* 连接池连接
*/
object _03StringTypeDemo {
def main(args: Array[String]): Unit = {
//连接池配置
val config = new GenericObjectPoolConfig
config.setMaxIdle(5) //最大空闲线程数
config.setMinIdle(2) //最小空闲数
config.setMaxTotal(10) //线程总数
//获取jedis的连接池对象
val pool = new JedisPool(config,"node01", 6379,10000,"123123")
//从连接池中获取一个具体的连接 对象
val jedis: Jedis = pool.getResource
//设置一个kv
jedis.set("name","mark")
//设置多个kv
jedis.mset("age","21","gender","m")
//自增1
jedis.incr("age")
//自减1
jedis.decr("age")
//自增2
jedis.incrBy("age",2)
//获取
val hobby: util.List[String] = jedis.mget("name","age","gender")
//输出
println(hobby)
//将线程归还给线程池
jedis.close()
}
}
3.2、Hash类型
Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。
结构:key field value
3.2.1、命令行操作
node01:6379> hset mark age 23
(integer) 1
node01:6379> hget mark age
"23"
node01:6379> hset mark age 23 gender m
(integer) 1
node01:6379> hmget mark age gender
1) "23"
2) "m"
#没有hincr,只有hincrby
node01:6379> hincr mark age
(error) ERR unknown command `hincr`, with args beginning with: `mark`, `age`,
node01:6379> hincrby mark age 2
(integer) 25
#没有hdecrby
node01:6379> hdecrby mark age 2
(error) ERR unknown command `hdecrby`, with args beginning with: `mark`, `age`, `2`,
node01:6379> hdel mark age
(integer) 1
node01:6379> hget mark age
(nil)
#不能直接删k
node01:6379> hdel mark
(error) ERR wrong number of arguments for 'hdel' command
node01:6379> hget mark gender
"m"
node01:6379> hdel mark gender
(integer) 1
node01:6379> hget mark gender
(nil)
node01:6379> hmset ss aa 1 bb 2 cc 3
OK
node01:6379> hmget ss aa bb cc
1) "1"
2) "2"
3) "3"
node01:6379> hkeys ss
1) "aa"
2) "bb"
3) "cc"
node01:6379> hvals ss
1) "1"
2) "2"
3) "3"
3.2.2、jedis操作
package Day01
import java.util
import redis.clients.jedis.{Jedis, JedisPool}
import scala.collection.mutable
object _04HashTypeDemo {
def main(args: Array[String]): Unit = {
//获取jedis的连接池对象
val pool = new JedisPool("qianfeng01", 6379)
//从连接池中获取一个具体的连接 对象
val jedis: Jedis = pool.getResource
//设置一个购物车信息
jedis.hset("xiaoming:shoppingcart","fruit","apple")
jedis.hset("xiaoming:shoppingcart","T恤","200")
//创建一个map
val map = new util.HashMap[String, String]()
map.put("computer","lenovo")
map.put("wanju","aotuman")
//参数可以是map
jedis.hset("xiaoming:shoppingcart",map)
//批量增加
jedis.hmset("xiaoming:shoppingcart",map)
//获取一条
jedis.hget("xiaoming:shoppingcart","computer")
//获取多条
jedis.hmget("xiaoming:shoppingcart","fruit","computer","wanju")
//删除
jedis.hdel("xiaoming:shoppingcart","computer","fruit")
//自增
jedis.hincrBy("xiaoming:shoppingcart","T恤",50)
//判断字段是否存在
jedis.hexists("xiaoming:shoppingcart","computer")
//字段存在不作任何操作,不存在则和hset一样
jedis.hsetnx("xiaoming:shoppingcart","computer","hasee")
//只获取字段名
jedis.hkeys("xiaoming:shoppingcart")
//只获取字段值
jedis.hvals("xiaoming:shoppingcart")
//获取字段数量
jedis.hlen("xiaoming:shoppingcart")
}
}
3.3、list类型
List是有序可重复的集合
ArrayList与LinkedList的区别
ArrayList使用数组方式存储数据,所以根据索引查询数据速度快,而新增或者删除元素时需要设计到位移操作,所以比较慢。
LinkedList使用双向链接方式存储数据,每个元素都记录前后元素的指针,所以插入、删除数据时只是更改前后元素的指针指向即可,速度非常快,然后通过下标查询元素时需要从头开始索引,所以比较慢,但是如果查询前几个元素或后几个元素速度比较快。
总结
arrayList在进行增删改时很麻烦
linkedList则无该问题,redis的list类型存储时采用linkedlist
redis存储list类型可以实现队列和堆栈,队列是先进先出,而堆栈是先进后出。
3.3.1、命令行操作
- 从左边存值(堆栈)
129.0.0.1Redis.assets6379> lpush list1 1 2 3 4 5 6
(integer) 6
- 从右边存值(队列)
129.0.0.1Redis.assets6379> rpush list1 a b c d
(integer) 10
- 查看List值
129.0.0.1Redis.assets6379> lrange list1 0 3
1) "6"
2) "5"
3) "4"
4) "3"
如果查看全部,使用以下命令:
129.0.0.1Redis.assets6379> lrange list1 0 -1
1) "6"
2) "5"
3) "4"
4) "3"
5) "2"
6) "1"
7) "a"
8) "b"
9) "c"
10) "d"
- 从两端弹出值
129.0.0.1Redis.assets6379> lpush list1 1 2 3 4 5 6
(integer) 6
129.0.0.1Redis.assets6379> lrange list1 0 -1
1) "6"
2) "5"
3) "4"
4) "3"
5) "2"
6) "1"
129.0.0.1Redis.assets6379> lpop list1
"6"
129.0.0.1Redis.assets6379> lrange list1 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
129.0.0.1Redis.assets6379> rpop list1
"1"
129.0.0.1Redis.assets6379> lrange list1 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
- 获取列表的长度
129.0.0.1Redis.assets6379> llen list1
(integer) 4
其他命令
-
删除列表中指定的值
LREM key count value
LREM命令会删除列表中前count个值为value的元素,返回实际删除的元素个数。根据count值的不同,该命令的执行方式会有所不同:
当count>0时, LREM会从列表左边开始删除。
当count<0时, LREM会从列表后边开始删除。
当count=0时,LREM删除所有值为value的元素。
-
获得/设置指定索引的元素值
LINDEX key index
LSET key index value
129.0.0.1Redis.assets6379> lindex lRedis.assetslist 2
"1"
129.0.0.1Redis.assets6379> lset lRedis.assetslist 2 2
OK
129.0.0.1Redis.assets6379> lrange lRedis.assetslist 0 -1
1) "6"
2) "5"
3) "2"
4) "2"
-
只保留列表指定片段,指定范围和LRANGE一致
LTRIM key start stop
129.0.0.1Redis.assets6379> lrange lRedis.assetslist 0 -1
1) "6"
2) "5"
3) "0"
4) "2"
129.0.0.1Redis.assets6379> ltrim lRedis.assetslist 0 2
OK
129.0.0.1Redis.assets6379> lrange lRedis.assetslist 0 -1
1) "6"
2) "5"
3) "0"
-
向列表中插入元素
LINSERT key BEFORE|AFTER pivot value
该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。
129.0.0.1Redis.assets6379> lrange list 0 -1
1) "3"
2) "2"
3) "1"
129.0.0.1Redis.assets6379> linsert list after 3 4
(integer) 4
129.0.0.1Redis.assets6379> lrange list 0 -1
1) "3"
2) "4"
3) "2"
4) "1"
-
将元素从一个列表转移到另一个列表中
RPOPLPUSH source destination
129.0.0.1Redis.assets6379> rpoplpush list newlist
"1"
129.0.0.1Redis.assets6379> lrange newlist 0 -1
1) "1"
129.0.0.1Redis.assets6379> lrange list 0 -1
1) "3"
2) "4"
3) "2"
3.3.2、jedis操作(java版本)
import redis.clients.jedis.Jedis;
import java.util.Random;
import java.util.UUID;
public class TaskProducer {
private static Jedis jedis = new Jedis("node02", 6379);
public static void main(String[] args) throws Exception {
Random r = new Random();
while (true) {
int nextInt = r.nextInt(1000);
Thread.sleep(2000 + nextInt);
String taskId = UUID.randomUUID().toString();
jedis.lpush("task-queue1", taskId);
System.out.println("生成一条任务信息:" + taskId);
}
}
}
import redis.clients.jedis.Jedis;
import java.util.Random;
public class TaskConsumer {
private static Jedis jedis = new Jedis("node02", 6379);
public static void main(String[] args) throws Exception {
Random r = new Random();
while (true) {
Thread.sleep(2000);
// 从task-queue1任务队列里取出一个任务,放到暂存队列里
String taskId = jedis.rpoplpush("task-queue1", "temp-queue1");
// 模拟处理任务
if (r.nextInt(19) % 9 == 0) {
// 任务处理失败,需要把任务信息从暂存队列里弹出来再放到任务队列里等待继续消费
jedis.rpoplpush("temp-queue1", "task-queue1");
System.out.println("任务处理失败:" + taskId);
} else {
jedis.rpop("temp-queue1");
System.out.println("任务处理成功:" + taskId);
}
}
}
}
3.4、set类型
Set类型的数据是有序且不可重复。
3.4.1、命令行操作
- 添加元素
129.0.0.1Redis.assets6379> sadd set1 1 2 3 3 4 5 5
(integer) 5
- 删除元素
129.0.0.1Redis.assets6379> sadd set1 1 2 3 3 4 5 5
(integer) 5
129.0.0.1Redis.assets6379> srem set1 3
(integer) 1
129.0.0.1Redis.assets6379> smembers set1
1) "1"
2) "2"
3) "4"
4) "5"
- 查看元素
129.0.0.1Redis.assets6379> smembers set1
1) "1"
2) "2"
3) "4"
4) "5"
- 判断元素是否存在
129.0.0.1Redis.assets6379> sismember set1 6
(integer) 0
运算命令
- 差集运算
129.0.0.1Redis.assets6379> sadd set3 2 3 4
(integer) 3
129.0.0.1Redis.assets6379> sadd set4 1 2 3
(integer) 3
129.0.0.1Redis.assets6379> sdiff set4 set3
1) "1"
129.0.0.1Redis.assets6379> sdiff set3 set4
1) "4"
- 交集运算
129.0.0.1Redis.assets6379> sinter set3 set4
1) "2"
2) "3"
- 并集运算
129.0.0.1Redis.assets6379> sunion set3 set4
1) "1"
2) "2"
3) "3"
4) "4"
其他命令
-
获得集合中元素的个数
SCARD key
129.0.0.1Redis.assets6379> smembers setA
1) "1"
2) "2"
3) "3"
129.0.0.1Redis.assets6379> scard setA
(integer) 3
-
从集合中弹出一个元素
SPOP key
129.0.0.1Redis.assets6379> spop setA
"1“
注意:由于集合是无序的,所有SPOP命令会从集合中随机选择一个元素弹出
3.4.2、jedis操作
import java.util
import redis.clients.jedis.Jedis
object _06SetTypeDemo {
def main(args: Array[String]): Unit = {
//使用java的redis客户端API jedis, 要连接linux上的redis服务,主要要修改redis.conf下的bind为主机名或者而是Ip
val jedis = new Jedis("node01", 6379)
jedis.auth("123456")
jedis.sadd("heros","superman","盖伦","daomei","毕加索")
//获取
val strings: util.Set[String] = jedis.smembers("heros")
import scala.collection.JavaConversions._
for(i<- strings){
println(i)
}
//删除 刀妹
println(jedis.srem("heros", "daomei"))
println("-----------删除后--------")
for(i<- jedis.smembers("heros")){
println(i)
}
//释放资源
jedis.close()
}
}
3.5、sortedSet类型
zset在设置时,会给设置一个分数,通过分数,可以进行排序。
3.5.1、命令行操作
- 添加元素
129.0.0.1Redis.assets6379> zadd zset1 1 haha 2 hehe 0 heihei
(integer) 3
- 删除元素
129.0.0.1Redis.assets6379> zrem zset1 haha
(integer) 1
- 获得排名在某个范围的元素列表
129.0.0.1Redis.assets6379> zrange zset1 0 3
1) "heihei"
2) "hehe"
129.0.0.1Redis.assets6379> zrevrange zset1 0 3
1) "hehe"
2) "heihei"
129.0.0.1Redis.assets6379> zrevrange zset1 0 3 withscores
1) "hehe"
2) "2"
3) "heihei"
4) "0"
其他命令
-
获得指定分数范围的元素
ZRANGEBYSCORE key min max [WITHSCORES]
[LIMIT offset count]
129.0.0.1Redis.assets6379> ZRANGEBYSCORE scoreboard 90 97 WITHSCORES
1) "wangwu"
2) "94"
3) "lisi"
4) "97"
129.0.0.1Redis.assets6379> ZRANGEBYSCORE scoreboard 70 100 limit 1 2
1) "wangwu"
2) "lisi"
-
增加某个元素的分数,返回值是更改后的分数。
ZINCRBY key increment member
129.0.0.1Redis.assets6379> ZINCRBY scoreboard 4 lisi
"101“
-
获得集合中元素的数量
ZCARD key
129.0.0.1Redis.assets6379> ZCARD scoreboard
(integer) 3
-
获得指定分数范围内的元素个数
ZCOUNT key min max
129.0.0.1Redis.assets6379> ZCOUNT scoreboard 80 90
(integer) 1
-
按照排名范围删除元素
ZREMRANGEBYRANK key start stop
129.0.0.1Redis.assets6379> ZREMRANGEBYRANK scoreboard 0 1
(integer) 2
129.0.0.1Redis.assets6379> ZRANGE scoreboard 0 -1
1) "lisi"
-
按照分数范围删除元素
ZREMRANGEBYSCORE key min max
129.0.0.1Redis.assets6379> zadd scoreboard 84 zhangsan
(integer) 1
129.0.0.1Redis.assets6379> ZREMRANGEBYSCORE scoreboard 80 100
(integer) 1
-
获取元素的排名
从小到大
ZRANK key member
129.0.0.1Redis.assets6379> ZRANK scoreboard lisi
(integer) 0
从大到小
ZREVRANK key member
129.0.0.1Redis.assets6379> ZREVRANK scoreboard zhangsan
(integer) 1
应用:商品销售排行榜
根据商品销售量对商品进行排行显示,定义sorted set集合,商品销售量为元素的分数。
定义商品销售排行榜key:itemsRedis.assetssellsort
写入商品销售量:
商品编号1001的销量是9,商品编号1002的销量是10
192.168.101.3Redis.assets7007> ZADD itemsRedis.assetssellsort 9 1001 10 1002
商品编号1001的销量加1
192.168.101.3Redis.assets7001> ZINCRBY itemsRedis.assetssellsort 1 1001
商品销量前10名:
192.168.101.3Redis.assets7001> zrevrange zset1 0 9 withscores
3.5.2、jedis操作
scala
import java.util
import redis.clients.jedis.{Jedis, Tuple}
object _07SortedSetTypeDemo {
def main(args: Array[String]): Unit = {
//使用java的redis客户端API jedis, 要连接linux上的redis服务,主要要修改redis.conf下的bind为主机名或者而是Ip
val jedis = new Jedis("node01", 6379)
jedis.auth("123456")
//添加几个商品销售量,销售量作为分数
jedis.zadd("rank",100,"毛衣1")
jedis.zadd("rank",110,"毛衣2")
jedis.zadd("rank",90,"毛衣3")
jedis.zadd("rank",120,"毛衣4")
jedis.zadd("rank",100,"毛衣5")
jedis.zadd("rank",80,"毛衣6")
jedis.zadd("rank",70,"毛衣7")
jedis.zadd("rank",88,"毛衣8")
jedis.zadd("rank",50,"毛衣9")
jedis.zadd("rank",200,"毛衣10")
jedis.zadd("rank",250,"毛衣11")
//获取销售量的前10名
import scala.collection.JavaConversions._
val strings: util.Set[String] = jedis.zrevrange("rank", 0, 9)
for(i<-strings){
println(i)
}
///获取销售量的前10名,并显示分数值(销售量)
val tuples: util.Set[Tuple] = jedis.zrevrangeWithScores("rank",0,9)
for(i<-tuples){
println(i)
}
jedis.close()
}
}
java1、
import redis.clients.jedis.Jedis;
import java.util.Random;
public class LolBoxPlayer {
private static Jedis jedis = new Jedis("node02", 6379);
public static void main(String[] args) throws Exception {
Random r = new Random();
String[] heros = {"盖伦","轮子妈","蒙多","亚索","木木","刀妹","提莫","炼金"};
while (true) {
int index = r.nextInt(heros.length);
String hero = heros[index];
Thread.sleep(500);
// 给英雄每次出场的分数加1,如果初次出场,zincrby方法会自动创建
jedis.zincrby("hero:ccl", 1, hero);
System.out.println(hero + "出场了");
}
}
}
java2、
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;
import java.util.Set;
public class LolBoxViewer {
private static Jedis jedis = new Jedis("node02", 6379);
public static void main(String[] args) throws Exception {
// 计数器
int i = 1;
while (true) {
Thread.sleep(3000);
System.out.println("第" + i + "次查看榜单");
// 从redis获取榜单排名信息,取5名
Set<Tuple> heros = jedis.zrevrangeWithScores("hero:ccl", 0, 4);
for (Tuple hero: heros) {
System.out.println(hero.getElement() + "---------------" + hero.getScore());
}
i ++;
System.out.println("");
}
}
}
1437

被折叠的 条评论
为什么被折叠?



