Redis 数据库
nosql(not only sql) 非关系型数据库
1 安装redis
1.1 获取源码包
先去官网(http://redis.io/download )下载一个源码工程(redis官网版本只支持linux/微软开源事业部维护了一个windows版本)
把安装包上传到服务器,解压缩
1.2 编译源码
redis的源码是c语言开发,编译redis源码需要安装gcc
- 安装gcc
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
scl enable devtoolset-9 bash
echo "source /opt/rh/devtoolset-9/enable" >> /etc/profile
source /etc/profile
#查看版本号
[root@doitedu03 ~]# gcc -v
gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)
-
解压redis源码
[root@doitedu03 ~]# tar -zxf redis-6.0.9.tar.gz -
编译安装
[root@doitedu03 ~]# cd redis-6.0.9/
编译
[root@doitedu03 redis-6.0.9]# make MALLOC=libc -
迁出可执行文件
[root@doitedu03 redis-6.0.9]# make install PREFIX=/usr/local/redis6
-
配置环境变量
vi /etc/profile
export REDIS_HOME=/opt/redis6
export PATH=$PATH:$REDIS_HOME/bin
- 启动redis服务
准备配置文件
[root@linux01 redis6]# cp /opt/apps/redis-6.0.9/redis.conf /usr/local/redis6/
- 修改 redis.conf中的服务绑定地址
# bind 127.0.0.1
bind 127.0.0.1 linux01
- 启动redis服务,并指定使用的配置文件
[root@linux01 redis6]# bin/redis-server ./redis.conf
2 Redis的启动命令
主节点启用哨兵模式(高可用,当主节点挂机之后,从节点变为主节点)
redis-sentinel
启动服务(/usr/local/redis6/下)
- bin/redis-server ./redis.conf 1>/dev/null 2>&1 &
默认的是前台启动,也可以在redis.conf下修改启动服务配置参数(修改后直接启动服务即为后台启动)
daemonize yes
开启客户端
bin/redis-cli -h linux01 -p 6379
3 Redis数据类型
http://redisdoc.com/
redis-cli --raw # 可以避免中文乱码
1 数据类型
1 String
set key val # 存储一个string
get key # 取值
type key # 查看key值的类型
EXISTS key # 判断key是否存在
incr key # 数字值 + 1
decr
incrby key number # 数字值 + number
DECRBY key
mset k1 v1 k2 v2 ... #可变的 set多个key的值
mget k1 k2 k3 ... #可变的 get多个key的值
del key1 key2 ... #删除多个key
expire key 20 # 设置数据的存储时间
ttl key # 查看key的剩余存储时间
setex key 20 val # 存储数据的时候指定存储时间
PERSIST key # 永久保存某个key值
#在redis中默认有16个库 0~15 默认使用的是0
select 2 # 切换库
flushdb # 清除当前库
keys * # 查看所有的keys(正则匹配)
keys n* # 正则匹配执行的key
flushall # 清除所有的库
2 List 队列
lpush ls1 e #队列左边添加
rpush #队列右边添加
lpush ls2 e1 e2 e3 #从队列左边弹出一个值
rpop # 队列右边弹出值
lrange ls2 0 -1 ---> e3 e2 e1
linux01:6379> lpush task1 1 3 5 7
(integer) 4
linux01:6379> lpush test2 2 4 6 8
(integer) 4
linux01:6379> RPOPLPUSH task1 test2
LINSERT sb after mr hcy # 指定元素位置擦混入数据 after before
#从一个list的尾部弹出一个元素插入到另一个list
RPOPLP USH key1 key2 ## 这是一个原子性操作
LREM test2 1 1 #移除n个指定的元素
llen # 查看列表的长度
lset key index newElement # 更新数据
3 set 去重
sadd key e1 e2 e3 e2 # 去重
scard key # 集合的长度
srem key e1 e2 # 移除多个元素
smembers # 查看集合中所有的元素
SMOVE key1 key2 e # 移动元素
sismember key e # 判断集合中元素是否存在
linux01:6379> sadd number1 1 2 3 4 5 6 7
(integer) 7
linux01:6379> sadd number2 6 7 8 9
(integer) 4
linux01:6379> sinter number1 number2 # 交集
1) "6"
2) "7"
linux01:6379> sunionnumber1 number2 # 并集
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
8) "8"
9) "9"
linux01:6379> Sdiff number1 number2 # 差集
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
SUNIONSTORE res number1 number2 # 求交集差集并集 保存结果到res中
SDIFFSTORE res number1 number2
SINTERSTORE res number1 number2
4 sorted-set
zadd
zrange withscore
zrevrange withscore
zcard
zrem
zcount key min maX
ZINCRBY KEY ....
zscore
ZRANGEBYSCORE teacher:face_score 80 100 limit 0 2
5 hash
hset key K V K V #可变的set 多个kv到该key
hget key field #获取值
hmget
hgetall key #拿出key中的所有值
hkeys #查看该key中的所有fields(即K)
hlen
hvals
hincrby key f val
hexists
hdel
6 bitmap
SETBIT
GETBIT
BITCOUNT
BITPOS
BITOP
BITFIELD
2 javaAPI
<!--引入操作redis的客户端API JEDIS-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.3.0</version>
</dependency>
<!-- apark操作redis-->
<dependency>
<groupId>com.redislabs</groupId>
<artifactId>spark-redis_2.12</artifactId>
<version>2.4.2</version>
</dependency>
<!-- PPOJECT--JOSNSTR JSONSTR---- OBJECT -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.4</version>
</dependency>
2.1 基本API
public class Deno1 {
public static void main(String[] args) {
Jedis jedis = new Jedis("linux01", 6379);
/**
* String类型的API
*/
jedis.set("name", "hgc");
String name = jedis.get("name");
jedis.keys("*");
jedis.mget("name", "age");
jedis.mset("name", "lss", "gender", "M");
jedis.rename("gender", "sex");
jedis.del("a", "b");
// jedis.linsert()
// jedis.exists()
// jedis.expire()
//jedis.ttl()
//jedis.setex()
/**
* List 数据类型
*
* 任务调度系统:
* 生产者不断产生任务,放入task-queue排队
* jedis.lpush()
* 消费者不断拿出任务来处理,同时放入一个tmp-queue暂存,如果任务处理成功,则清除tmp-queue,
* jedis.rpoplpush()
* tmp-queue:
* 成功
* jedis.lpop()
* 失败
* jedis.lpop() ---> task-queue
* 10
* % 3 == 1
**/
//jedis.lpop()0
// jedis.lpush()
//jedis.lrange()
//jedis.llen()
//jedis.rpoplpush()
// jedis.lset()
System.out.println(name);
jedis.close();
}
}
2.2 案例
2.2.1 任务队列案例
务调度系统:
* 生产者不断产生任务,放入task-queue排队
* 消费者不断拿出任务来处理,同时放入一个tmp-queue暂存,如果任务处理成功,则清除tmp-queue,
生产任务
/**
* 不断的向任务队列中生产任务
*/
public class Producter {
public static void main(String[] args) throws InterruptedException {
Jedis jedis = new Jedis("linux01", 6379);
int i = 0 ;
while (true){
jedis.lpush("task-sequence" , "task-"+i) ;
System.out.println("产生任务 task-"+i);
Thread.sleep(2000);
i++ ;
}
}
}
消费任务
/**
* 从任务队列中取任务
* 将任务存储在临时队列中
* 处理任务 如果任务失败再放回到原来的队列中
*/
public class Consummer {
public static void main(String[] args) throws InterruptedException {
// 获取客户端
Jedis jedis = new Jedis("linux01", 6379);
Random random = new Random();
// 取任务 存储在临时队列中
while (true){
int i = random.nextInt(10);
jedis.rpoplpush("task-sequence" , "tmp_sequence");
Thread.sleep(2000);
if(jedis.llen("task-sequence")==0){
Thread.sleep(3000);
}
String taskID = jedis.lpop("tmp_sequence");
if(i%3==1){
System.out.println("处理的任务失败了: "+taskID);
jedis.lpush("task-sequence",taskID) ;
}else {
System.out.println("当前正在处理的任务是: "+taskID);
}
}
}
}
2.2.2 热门topN案例
/**
* 数组
* 随机获取
* 对应的 +1值
*/
public class Player {
public static void main(String[] args) throws InterruptedException {
Jedis jedis = new Jedis("linux01", 6379);
// 待出场的英雄们
String[] heros = new String[]{"娜娜", "慧慧", "奔奔", "小康", "baby", "小明", "涛哥"};
for (String hero : heros) {
jedis.zadd("heros", 0 ,hero) ;
}
Random random = new Random();
while (true){
int index = random.nextInt(heros.length);
String hero = heros[index];
System.out.println(hero+"踏着五彩祥云出场了....");
//jedis.zadd("heros" ,1 ,hero) ;
jedis.zincrby("heros",1 , hero) ;
Double heros1 = jedis.zscore("heros", hero);
System.out.println(hero+"第"+ heros1 +"出场了");
Thread.sleep(200);
}
}
}
public class ShowTopN {
public static void main(String[] args) throws InterruptedException {
Jedis jedis = new Jedis("linux01", 6379);
while (true){
Set<Tuple> set = jedis.zrevrangeWithScores("heros", 0, 2);
System.out.println(set);
Thread.sleep(5000);
}
}
}