Rides再次学习2

rides的学习与使用

1.key通用操作

1-1.key 特征

key是一个字符串,通过key获取redis中保存的数据

key应该设计哪些操作?

  • 对于key自身状态的相关操作,例如:删除,判定存在,获取类型等
  • 对于key有效性控制相关操作,例如:有效期设定,判定是否有效,有效状态的切换等
  • 对于key快速查询操作,例如:按指定策略查询key

1-2.key 基本操作

1
2
3
4
5
set str str 
hset hash hash1 hash1
lpush list list1
sadd set set1
zadd zset1 1 zsetel
  • 删除指定key
1
2
3
del key

del zsetl
  • 获取key是否存在
1
2
3
exists key

exists str
  • 获取key的类型
1
2
3
4
5
type key

type zset1
type str
type hash
  • 为指定key设置有效期
1
2
3
4
5
6
7
8
9
expire key seconds
pexpire key milliseconds
expireat key timestamp
pexpireat key milliseconds-timestamp

expire str 3
get str
get str
get str -->nil
  • 获取key的有效时间
1
2
3
4
5
6
ttl key
pttl key

expire list 30
ttl list
-2 不存在、-1 存在、有效期 返回时间
  • 切换key从时效性转换为永久性
1
persist key
  • 查询key
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
keys pattern

127.0.0.1:6379> set list2 list2
OK
127.0.0.1:6379> persist list2
(integer) 0
127.0.0.1:6379> expire list2 60
(integer) 1
127.0.0.1:6379> ttl list2
(integer) 56
127.0.0.1:6379> persist list2
(integer) 1
127.0.0.1:6379> ttl list2
(integer) -1
127.0.0.1:6379> persist str
(integer) 0
  • 查询模式规则
1
2
3
* 匹配任意数量的任意符号 
? 配合一个任意符号
[] 匹配一个指定符号
keys * 查询所有
keys it* 查询所有以it开头<br/
keys *heima 查询所有以heima结尾
keys ??heima 查询所有前面两个字符任意,后面以heima结尾
keys user:? 查询所有以user:开头,最后一个字符任意
keys u[st]er:1 查询所有以u开头,以er:1结尾,中间包含一个字母,s或t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
127.0.0.1:6379> set str str
OK
127.0.0.1:6379> set str1 str1
OK
127.0.0.1:6379> keys *
1) "str"
2) "str1"
127.0.0.1:6379> set name i
OK
127.0.0.1:6379> set i name
OK
127.0.0.1:6379> keys *
1) "name"
2) "i"
3) "str"
4) "str1"
127.0.0.1:6379> keys i*
1) "i"
127.0.0.1:6379> keys s*
1) "str"
2) "str1"
127.0.0.1:6379> set smr smr
OK
127.0.0.1:6379> keys s?r
1) "smr"
2) "str"
127.0.0.1:6379> keys ????
1) "name"
2) "str1"
127.0.0.1:6379> keys n[abc]me
1) "name"
127.0.0.1:6379> set nbme nbme
OK
127.0.0.1:6379> set nwme nwme
OK
127.0.0.1:6379> keys n[aw]me
1) "nwme"
2) "name"
127.0.0.1:6379> keys *
1) "nbme"
2) "nwme"
3) "smr"
4) "name"
5) "str"
6) "i"
7) "str1"
  • 为key改名
1
2
3
4
5
6
7
8
9
10
11
12
13
rename key newkey
renamenx key newkey

set str str
set str2 str2
rename str str3
rename str3 str2
-->str2被str3覆盖了
get str2 -->str

set str1 str1
renamenx str1 str2 -->0
renamenx str1 str3 -->1
  • 对所有key排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sort

127.0.0.1:6379> lpush aa 123 321 222
(integer) 3
127.0.0.1:6379> lrange aa 0 -1
1) "222"
2) "321"
3) "123"
127.0.0.1:6379> sort aa
1) "123"
2) "222"
3) "321"
127.0.0.1:6379> lrange aa 0 -1
1) "222"
2) "321"
3) "123"
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]
  • 其他key通用操作
1
help @generic

2.数据库通用操作

2-1.key 的重复问题

  • key是由程序员定义的
  • redis在使用过程中,伴随着操作数据量的增加,会出现大量的数据以及对应的key
  • 数据不区分种类、类别混杂在一起,极易出现重复或冲突

解决方案:

  • redis为每个服务提供有16个数据库,编号从0到15
  • 每个数据库之间的数据相互独立

2-35

2-2.db 基本操作

切换数据库

1
2
3
4
5
6
7
8
select index

127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> select 15
OK
127.0.0.1:6379[15]> select 0
OK

其他操作

1
2
3
4
5
6
7
quit
ping
echo message

echo abcdefg -->输出信息
ping -->PONG 测试联通数据库
quit 退出

数据移动

1
2
3
4
5
6
7
8
9
10
11
move key db

set name 1
select 1
get name -->nil
select 0
move name 1 ->1,移动剪切
get name -->nil
移动操作保证数据库里没有改数据,有该数据,移动不了
set name 2
move name 1 ->0

数据清除

1
2
3
dbsize		-->看数据库里有多少key
flushdb -->删除当前数据库数据
flushall -->删除所有数据库信息

3.Jedis

3-1.编程语言与redis

Java语言连接redis服务:Jedis

3-2.项目练习

  • jar包导入

下载地址:https://mvnrepository.com/artifact/redis.clients/jedis

  • 基于maven
1
2
3
4
5
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>

代码:String、list、hash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class JedisTest {
@Test
public void testJedis(){
//1.连接redis
Jedis jedis = new Jedis("127.0.0.1", 6379);
//2.操作redis
jedis.set("name","itheima");
String name = jedis.get("name");
System.out.println(name);
//3.关闭连接
jedis.close();
}
@Test
public void testList(){
//1.连接redis
Jedis jedis = new Jedis("127.0.0.1", 6379);
//2.操作redis
jedis.lpush("list1","a","b","c");
jedis.rpush("list1","x");
List<String> list1 = jedis.lrange("list1", 0, -1);
for(String s : list1){
System.out.println(s);
}
System.out.println(jedis.llen("list1"));
System.out.println();
//3.关闭连接
jedis.close();
}
@Test
public void testHash(){
//1.连接redis
Jedis jedis = new Jedis("127.0.0.1", 6379);
//2.操作redis
jedis.hset("hash1","a1","b1");
jedis.hset("hash1","a2","a2");
jedis.hset("hash1","a3","b3");
Map<String, String> hash1 = jedis.hgetAll("hash1");
System.out.println(hash1);
System.out.println(jedis.hlen("hash1"));
System.out.println();
//3.关闭连接
jedis.close();
}
}

3-3.项目案例:服务调用次数控制

​ 人工智能领域的语义识别与自动对话将是未来服务业机器人应答呼叫体系中的重要技术,百度自研用户评价语义识别服务,免费开放给企业试用,同时训练百度自己的模型。现对试用用户的使用行为进行限速,限制每个用户每分钟最多发起10次调用

  • 案例要求

    • 设定A、B、C三个用户
    • A用户限制10次/分调用,B用户限制30次/分调用,C用户不限制
  • 需求分析

    • 设定一个服务方法,用于模拟实际业务调用的服务,内部采用打印模拟调用
    • 在业务调用前服务调用控制单元,内部使用redis进行控制,参照之前的方案
    • 对调用超限使用异常进行控制,异常处理设定为打印提示信息
    • 主程序启动3个线程,分别表示3种不同用户的调用
  • 要求

    • 后续1:对业务控制方案进行改造,设定不同用户等级的判定(做到)
    • 后续2:将不同用户等级对应的信息、限制次数等设定到redis中,使用hash保存

业务层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class Service {
//A用户限制10次/分调用,B用户限制30次/分调用,C用户不限制
private String name;
private int num;
private int count;
public Service(String name) {
this.name = name;
if (name == "A") {
this.num = 10;
this.count = 0;
} else if (name == "B") {
this.num = 30;
this.count = 0;
} else if (name == "C") {
this.count = 1;
}
}
public void Service() {
Jedis jedis = new Jedis("127.0.0.1",6379);
String value = jedis.get("compid:" + name);
//判断该值是否存在
try {
if (value == null) {
if (count == 0) {
//不存在,A用户限制10次/分调用,B用户限制30次/分调用
jedis.setex("compid:" + name, 60, Long.MAX_VALUE - num + "");
} else {
//C用户不限制
jedis.set("compid:" + name, "0");
}
} else {
//存在,自增,调用业务
Long val = jedis.incr("compid:" + name);
if (count == 0) {
business(name, num - (Long.MAX_VALUE - val));
} else {
//c
business(name, val);
}
}
} catch (JedisDataException e) {
System.out.println(name+"使用已经到达次数上限,请升级会员级别");
return;
} finally {
jedis.close();
}
}
//业务操作
public void business(String id, Long val) {
System.out.println("用户:" + id + " 业务操作执行第" + val + "次");
}
}

线程+main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class MyThead implements Runnable{
Service sc;
public MyThead(String name){
sc=new Service(name);
}
@Override
public void run() {
while (true){
try {
sc.Service();
Thread.sleep(500L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
//A用户限制10次/分调用,B用户限制30次/分调用,C用户不限制
MyThead a = new MyThead("A");
MyThead b = new MyThead("B");
MyThead c = new MyThead("C");
Thread t1=new Thread(a);
Thread t2=new Thread(b);
Thread t3=new Thread(c);
t1.start();
t2.start();
t3.start();
}
}

3-4.Jedis简易工具类开发

  • 封装连接参数: jedis.properties
1
2
3
4
redis.host=127.0.0.1
redis.port=6379
redis.maxTotal=30
redis.maxIdle=10
  • 工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class JedisUtils {
private static JedisPool jp = null;
private static String host = null;
private static int port;
private static int maxTotal;
private static int maxIdle;
//静态代码块初始化资源
static {
ResourceBundle rb = ResourceBundle.getBundle("redis");
host = rb.getString("redis.host");
port = Integer.parseInt(rb.getString("redis.port"));
maxTotal = Integer.parseInt(rb.getString("redis.maxTotal"));
maxIdle = Integer.parseInt(rb.getString("redis.maxIdle"));
JedisPoolConfig jpc = new JedisPoolConfig();
jpc.setMaxTotal(maxTotal);
jpc.setMaxIdle(maxIdle);
jp = new JedisPool(jpc,host,port);
}
//对外访问接口,提供jedis连接对象,连接从连接池获取
public static Jedis getJedis(){
return jp.getResource();
}
//测试连接
public static void main(String[] args){
JedisUtils.getJedis();
}
}

替换

1
2
//Jedis jedis = new Jedis("127.0.0.1",6379);
Jedis jedis = JedisUtils.getJedis();

3-5.可视化客户端

Redis Desktop Manager

Redis可视化工具Redis Desktop Manager 2019.0

4.基于Linux环境安装Redis

4-1.基于Center OS7安装Redis

  • 打开linux,我用SecureCRT工具,打开官网,看代码
1
2
3
4
5
wget http://download.redis.io/releases/redis-5.0.8.tar.gz
tar xzf redis-5.0.8.tar.gz
cd redis-5.0.8
make
make install
  • 因为个人刚搞linux,没有安装gcc,报错,所以要安装
1
2
3
4
5
6
7
8
9
...
CC adlist.o
/bin/sh: cc: 未找到命令
make[1]: *** [adlist.o] 错误 127
...
安装
yum install gcc-c++
make distclean 清空上次编译失败残留文件
make && make install 执行编译及安装
  • 参考

安装redis出现cc adlist.o /bin/sh:1:cc:not found的解决方法

CentOSt7安装Redis错误

4-2.实验

1.登录验证

1
2
3
4
5
6
7
8
9
10
11
cd redis-5.0.8 
cd src
返回上一级
cd ..
[root@localhost redis-5.0.8]# redis-server
克隆一个新的(clone session)
cd redis-5.0.8
[root@localhost redis-5.0.8]# redis-cli
set set set2
get set
能拿到set2,安装成功

2.换端口

1
2
3
cd redis-5.0.8 
redis-server --port 6380
redis-cli -p 6380

3.查看配置文件,配置文件启动

1
2
3
4
5
6
7
8
9
10
11
[root@localhost redis-5.0.8]# ll
看一下,复制到这里
cat redis.conf | grep -v "#" | grep -v "^$" > redis_6379.conf
修改
vim redis_6379.conf
直接删除,dd一行
i 插入
daemonize yes
logfile "6379.log"
dir /root/redis-5.0.8/data
:wq 保存退出

3-1

  1. 补充:创建个目录,放配置文件
1
2
3
4
mkdir data
cd data
pwd 获取路径
/root/redis-5.0.8/data
  1. 启动
1
2
3
4
5
6
7
8
9
10
redis-server redis-6379.conf
ps -ef | grep redis-
结果:
root 68557 1 0 15:55 ? 00:00:00 redis-server *:6379
root 68562 67617 0 15:55 pts/0 00:00:00 grep --color=auto redis-
克隆,开验证
redis-cli 默认6379

关闭
redis-cli -p 6379 shutdown

4.多个配置文件,转移到conf

1
2
3
4
5
6
7
8
9
10
11
12
13
mkdir conf
//转移
mv redis-6379.conf conf
cd conf
ll
复制多个conf
cp redis-6379.conf redis-6380.conf
vim redis-6380.conf
i,修改
port 6380
daemonize yes
logfile "6380.log"
dir /root/redis-5.0.8/data

3-3

5.启动

1
2
3
4
5
6
7
8
redis-server conf/redis-6379.conf
redis-server conf/redis-6380.conf
克隆
redis-cli -p 6379
redis-cli -p 6380
关掉
redis-cli -p 6379 shutdown
redis-cli -p 6380 shutdown

4-3.理论

1.Redis基础环境设置

  • 创建软链接
    • ln -s 原始目录名 快速访问目录名
  • 创建配置文件管理目录
    • mkdir conf
    • mkdir config
  • 创建数据文件管理目录
    • mkdir data

2.Redis服务启动

  • 默认配置启动
    • redis-server
    • redis-server –-port 6379
    • redis-server –-port 6380 ……
  • 指定配置文件启动
    • redis-server redis.conf
    • redis-server redis-6379.conf
    • redis-server redis-6380.conf ……
    • redis-server conf/redis-6379.conf
    • redis-server config/redis-6380.conf ……

3.Redis客户端连接

  • 默认连接
    • redis-cli
  • 连接指定服务器
    • redis-cli -h 127.0.0.1
    • redis-cli –port 6379
    • redis-cli -h 127.0.0.1 –port 6379

4.Redis服务端配置

  • 基本配置
    • daemonize yes: 以守护进程方式启动,使用本启动方式,redis将以服务的形式存在,日志将不再打印到命令窗口中
    • port 6***:设定当前服务启动端口号
    • dir “/自定义目录/redis/data“: 设定当前服务文件保存位置,包含日志文件、持久化文件(后面详细讲解)等
    • logfile “6***.log“: 设定日志文件名,便于查阅
-------------本文结束感谢您的阅读-------------

本文标题:Rides再次学习2

文章作者:Linhuide

发布时间:2020年04月10日 - 22:04

最后更新:2020年04月17日 - 19:04

原始链接:https://linhuide.github.io/post/cef8fda2.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

坚持原创技术分享,您的支持将鼓励我继续创作!