总是听说很多javaweb系统用redis或memcache做缓存,具体怎么操作的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了总是听说很多javaweb系统用redis或memcache做缓存,具体怎么操作的相关的知识,希望对你有一定的参考价值。

其实就相当于在应用程序和数据库之间开了一块内存区域,将一些高频访问的数据放在其中,避免每次都请求数据库。至于之所以用memcached和redis,而不是自己在程序里开个hashmap,是因为这块区域可以共享且容易管理,在集群环境下更方便使用。

有些做法是直接将数据序列化后存在redis的string或是memcached中,也有些其他做法是利用redis特有的数据结构存储一些关系,例如用sorted set存排行榜,string用来计数,set做一些倒排索引、用户好友关系之类的。我觉得这些都可以称之为缓存。
参考技术A redis是一个内存数据库(它的数据存储在内存中,一段时间之后会自动读入硬盘),和关系型数据库(mysql,oracle)有很大的不同,但它也是一个数据库,它需要一套自己的操作API。既然是缓存,那么你就需要把那些经常需要读取的数据放到redis中就OK,具体怎么操作?不就是去学习怎么连接redis,然后用redis的操作API做增删改查吗。。。本回答被提问者采纳

linux系统mysql数据库redis主从复制

第一章: 关系型和非关系型

1.实质。
非关系型数据库的实质:非关系型数据库产品是传统关系型数据库的功能阉割版本,通过减少用不到或很少用的功能,来大幅度提高产品性能。

2.价格。
目前基本上大部分主流的非关系型数据库都是免费的。而比较有名气的关系型数据库,比如Oracle、DB2、MSSQL是收费的。虽然Mysql免费,但它需要做很多工作才能正式用于生产。

3.功能。

? 实际开发中,有很多业务需求,其实并不需要完整的关系型数据库功能,非关系型数据库的功能就足够使用了。这种情况下,使用性能更高、成本更低的非关系型数据库当然是更明智的选择。

非关系型数据库的优势:

  1. 性能
    NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高。

  2. 可扩展性
    同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。

关系型数据库的优势:

  1. 复杂查询
    可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。

  2. 事务支持
    使得对于安全性能很高的数据访问要求得以实现。

对于这两类数据库,对方的优势就是自己的弱势,反之亦然。

=======================================

第二章:Redis特点及应用场景

特点

1.速度快
Redis 所有的数据都存放在内存中
Redis 使用c语言实现
Redis 使用单线程架构

2.基于键值对的数据结构服务器
5种数据结构:字符串,哈希,列表,集合,有序集合

3.丰富的功能
提供了键过期功能,可以实现缓存
提供了发布订阅功能,可以实现消息系统
提供了pipeline功能,客户端可以将一批命令一次性传到 Redis,减少了网络开销

4.简单稳定
源码很少,3.0 版本以后 5 万行左右.
使用单线程模型法,是的Redis服务端处理模型变得简单.
不依赖操作系统的中的类库

5.客户端语言多
java,PHP,python,C,C++,Nodejs等

6.数据持久化
把所有的数据都存在内存中
RDB和AOF

7.主从复制
8.高可用和分布式
哨兵 redis-sentinel
集群 redis-cluster

应用场景
1.缓存-键过期时间
缓存session会话
缓存用户信息,找不到再去mysql查,查到然后回写到 redis
优惠卷过期时间

2.排行榜-列表&有序集合
热度排名排行榜
发布时间排行榜

3.计数器应用-天然支持计数器
帖子浏览数
视频播放次数
商品浏览数

4.社交网络-集合
踩/赞,粉丝,共同好友/喜好,推送,打标签

5.消息队列系统-发布订阅
配合elk实现日志收集

=======================================

第三章:安装部署

1.目录规划

redis 下载目录:/data/soft/
redis 安装目录:/opt/redis_cluster/redis_{PORT}/{conf,logs,pid}
redis 数据目录:/data/redis_cluster/redis_{PORT}/redis_{PORT}.rdb
redis 运维脚本:/root/scripts/redis_shell.sh

2.安装操作命令

#创建软件下载目录
cd /data/soft/
#创建redis存放数据目录
mkdir -p /data/redis_cluster/redis_6379
#创建软件安装目录,包含配置文件,pid,日志存放位置
mkdir -p /opt/redis_cluster/redis_6379/{conf,pid,logs}
#下载reids,解压到安装目录,并做软链接
wget http://download.redis.io/releases/redis-3.2.9.tar.gz
tar zxf redis-3.2.9.tar.gz -C /opt/redis_cluster/
ln -s /opt/redis_cluster/redis-3.2.9/ /opt/redis_cluster/redis
#进入安装目录进行安装
cd /opt/redis_cluster/redis
make && make install

3.配置文件

cd /opt/redis_cluster/redis_6379/conf/
cat >redis_6379.conf <<EOF
# 以守护进程模式启动
daemonize yes
# 绑定的主机地址
bind 10.0.0.51
# 监听端口
port 6379
# pid 文件和 log 文件的保存地址
pidfile /opt/redis_cluster/redis_6379/pid/redis_6379.pid
logfile /opt/redis_cluster/redis_6379/logs/redis_6379.log
# 设置数据库的数量,默认数据库为 0
databases 16
# 指定本地持久化文件的文件名,默认是 dump.rdb
dbfilename redis_6379.rdb
# 本地数据库的目录
dir /data/redis_cluster/redis_6379
EOF

4.启动redis实列

redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf

5.检查是否启动

ps -ef|grep redis 
netstat -lntup|grep 6379 

6.配置hosts文件

cat >/etc/hosts<<EOF 
10.0.0.51  db01
10.0.0.52  db02
10.0.0.53  db03
EOF 

7.测试

[root@db-01 ~]# redis-cli -h db01 
[root@db-01 ~]# redis-cli -h db01 
db01:6379> set k1 v1
OK
db01:6379> get k1
"v1"
db01:6379> 

=======================================

第四章:redis基本操作命令

全局命令
1.查看所有的key
keys *

2.查看有多少个key,注意,是估值
DBSIZE

3.查看是否存在这个KEY
EXISTS k1
EXISTS k1 k2 k3

状态码:
0 表示这个key不存在
1 表示这个key存在
N 表示有的N个key存在

4.删除key
DEL k1
DEL k1 k2 k3

状态码:
0 表示这个key不存在
1 表示这个key存在,并且删除成功
N 表示有的N个key存在,并且删除N个Key

5.键过期
设置过期时间
EXPIRE k1 100

取消过期时间
PERSIST k2

状态码:
0: 表示这个key原来就没有设置过期时间
1: 表示这个key存在过期时间,并且取消成功

查看key是否过期
TTL k1

状态码:
-1: 这个key存在,但是没有设置过期时间
-2: 这个key不存在
N: 表示这个key还有多久过期,时间是秒

过期后的key直接会被删除

=======================================

字符串操作:
1.设置一个key
set k1 v2

2.查看一个key
get k1

3.设置多个key
MSET k1 v1 k2 v2 k3 v3

4.查看多个key
MGET k1 k2 k3

5.天然计数器
set k1 100

INCR k1 #默认加1
INCRBY k1 N #加N

=======================================

列表:
插入列表:
LPUSH:从列表左侧插入数据
RPUSH:从列表右侧插入数据

db01:6379> LPUSH list1 A
(integer) 1
db01:6379> LPUSH list1 B
(integer) 2
db01:6379> LPUSH list1 C
(integer) 3
db01:6379> RPUSH list1 D
(integer) 4

查看列表的长度:
db01:6379> LLEN list1
(integer) 4

查看列表的内容:
db01:6379> LRANGE list1 0 -1

  1. "C"
  2. "B"
  3. "A"
  4. "D"

删除列表元素:
LPOP: 从列表左侧删除
RPOP: 从列表右侧删除

db01:6379> LPOP list1
"C"
db01:6379> RPOP list1
"D"
db01:6379> LRANGE list1 0 -1

  1. "B"
  2. "A"

删除列表内容:
db01:6379> DEL list1
(integer) 1

=======================================

哈希:

生成一个hash类型:
db01:6379> hmset user:1000 username zhangya age 27 job it
OK

查看hash里的一个值
db01:6379> HGET user:1000 job
"it"
db01:6379> HGET user:1000 username
"zhangya"

查看hash里的多个值
db01:6379> HMGET user:1000 username age job

  1. "zhangya"
  2. "27"
  3. "it"

查看hash里的所有的值
db01:6379> HGETALL user:1000

  1. "username"
  2. "zhangya"
  3. "age"
  4. "27"
  5. "job"
  6. "it"

=======================================

集合:

创建集合
sadd set1 1 2 3
sadd set2 3 4 5

查看集合的成员:
db01:6379> SMEMBERS set1

  1. "1"
  2. "2"
  3. "3"
    db01:6379> SMEMBERS set2
  4. "3"
  5. "4"
  6. "5"

查看集合的差集,以前面一个集合为基准对比后面的
db01:6379> SDIFF set1 set2

  1. "1"
  2. "2"
    db01:6379> SDIFF set2 set1
  3. "4"
  4. "5"

查看集合的交集
db01:6379> SINTER set1 set2

  1. "3"

查看集合的并集
db01:6379> SUNION set1 set2

  1. "1"
  2. "2"
  3. "3"
  4. "4"
  5. "5"

集合不允许出现重复的值
db01:6379> SADD set1 1 2 3 4 5 6 6 7 7
(integer) 4
db01:6379> SMEMBERS set1

  1. "1"
  2. "2"
  3. "3"
  4. "4"
  5. "5"
  6. "6"
  7. "7"

===================================

第五章: Redis持久化

1.RDB和AOF优缺点
RDB: 快照,把当前内存里的状态快照到磁盘上
优点: 恢复速度快
缺点: 可能会丢失数据

AOF: 类似于mysql的binlog,重写,1秒写一次
优点: 安全,有可能会丢失1秒的数据
缺点: 文件比较大,恢复速度慢

2.配置RDB

vim /opt/redis_cluster/redis_6379/conf/redis_6379.conf
save 900 1
save 300 10
save 60 10000
dir /data/redis_cluster/redis_6379/
dbfilename redis_6379.rdb

结论:
1.执行shutdown的时候,内部会自动执行bgsave,然后再执行shutdown
2.pkill kill killall 都类似于执行shutdown命令.会触发bgsave持久化
3.恢复的时候,rdb文件名称要和配置文件里写的一样
4.如果没有配置save参数,执行shutdown不会自动bgsave持久化
5.如果没有配置save参数,可以手动执行bgsave触发持久化保存

3.配置AOF

vim /opt/redis_cluster/redis_6379/conf/redis_6379.conf
appendonly yes
appendfsync always
appendfsync everysec
appendfsync no

实验:
如果aof和rdb文件同时存在,redis会如何读取:

实验步骤:
1.插入一条数据
aof: 有记录
rdb: 没有记录
2.复制到其他地方
3.把redis停掉
4.清空数据目录
5.把数据文件拷贝过来
aof: 有记录
rdb: 没有记录
6.启动redis
7.测试,如果有新插入的数据,就表示读取的是aof,如果没有,就表示读取的是rdb

实验结论:
如果2种数据格式都存在,优先读取aof

========================================

第六章: Redis用户认证

1.配置文件

vim /opt/redis_cluster/redis_6379/conf/redis_6379.conf
requirepass 123456

2.使用密码登录
两种方式:
第一种:

[root@db-01 ~]# redis-cli -h db01
db01:6379> get k_1
(error) NOAUTH Authentication required.
db01:6379> AUTH 123456
OK
db01:6379> get k_1
"v_1"

第二种:

[root@db-01 ~]# redis-cli -h db01 get k_1
(error) NOAUTH Authentication required.
[root@db-01 ~]# redis-cli -h db01 -a 123456 get k_1
"v_1"

========================================

第七章: Redis主从复制

快速创建第二台redis节点命令:
rsync -avz /opt/* db02:/opt/
rsync -avz /data db02:/
cd /opt/redis_cluster/redis
make install
sed -i ‘s#51#52#g‘ /opt/redis_cluster/redis_6379/conf/redis_6379.conf
rm -rf /data/redis_cluster/redis_6379/*
redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf

配置主从方法:
方法1: 临时生效

[root@db-02 ~]# redis-cli -h 10.0.0.52
10.0.0.52:6379> SLAVEOF 10.0.0.51 6379
OK

方法2: 写入配置文件

vim /opt/redis_cluster/redis_6379/conf/redis_6379.conf
SLAVEOF 10.0.0.51 6379

主从复制流程:
1.从节点发送同步请求到主节点
2.主节点接收到从节点的请求之后,做了如下操作

  • 立即执行bgsave将当前内存里的数据持久化到磁盘上
  • 持久化完成之后,将rdb文件发送给从节点
    3.从节点从主节点接收到rdb文件之后,做了如下操作
  • 清空自己的数据
  • 载入从主节点接收的rdb文件到自己的内存里
    4.后面的操作就是和主节点实时的了

取消主从复制

SLAVEOF no one

注意!!!
1.从节点只读不可写
2.从节点不会自动故障转移,它会一直同步主
10.0.0.52:6379> set k1 v1
(error) READONLY You can‘t write against a read only slave.
3.主从复制故障转移需要人工介入

  • 修改代码指向REDIS的IP地址
  • 从节点需要执行SLAVEOF no one

注意!!!
1.从节点会清空自己原有的数据,如果同步的对象写错了,就会导致数据丢失

安全的操作:
1.无论是同步,无论是主节点还是从节点
2.先备份一下数据

===================================================================

第八章: Redis哨兵

哨兵操作

1.安装部署3个单节点

!!!!注意!!!!

三个节点修改为自己的IP地址

mkdir -p /data/redis_cluster/redis_6379
mkdir -p /opt/redis_cluster/redis_6379/{conf,pid,logs}
cd /data/soft/
wget http://download.redis.io/releases/redis-3.2.9.tar.gz
tar zxf redis-3.2.9.tar.gz -C /opt/redis_cluster/
ln -s /opt/redis_cluster/redis-3.2.9/ /opt/redis_cluster/redis
cd /opt/redis_cluster/redis
make && make install
cd /opt/redis_cluster/redis_6379/conf/
cat >redis_6379.conf <<EOF
daemonize yes
bind 10.0.0.5x
port 6379
pidfile /opt/redis_cluster/redis_6379/pid/redis_6379.pid
logfile /opt/redis_cluster/redis_6379/logs/redis_6379.log
databases 16
dbfilename redis_6379.rdb
dir /data/redis_cluster/redis_6379
EOF

2.安装部署3个哨兵节点

!!!!注意!!!!

三个节点的bind IP修改为自己的IP地址

mkdir -p /data/redis_cluster/redis_26379
mkdir -p /opt/redis_cluster/redis_26379/{conf,pid,logs}

3.配置哨兵的配置文件

cat >/opt/redis_cluster/redis_26379/conf/redis_26379.conf << EOF
bind 10.0.0.5x
port 26379
daemonize yes
logfile /opt/redis_cluster/redis_26379/logs/redis_26379.log
dir /data/redis_cluster/redis_26379
#mymaster 主节点别名 主节点 ip 和端口,判断主节点失败,两个 sentinel 节点同意
sentinel monitor mymaster 10.0.0.51 6379 2 
#选项指定了 Sentinel 认为服务器已经断线所需的毫秒数。
sentinel down-after-milliseconds mymaster 3000
#向新的主节点发起复制操作的从节点个数,1 轮询发起复制
sentinel parallel-syncs mymaster 1
#故障转移超时时间
sentinel failover-timeout mymaster 18000
EOF

4.启动所有的单节点

redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf 

5.配置主从复制

redis-cli -h db02 slaveof 10.0.0.51 6379
redis-cli -h db03 slaveof 10.0.0.51 6379

6.启动哨兵

redis-sentinel /opt/redis_cluster/redis_26379/conf/redis_26379.conf

7.验证主节点

redis-cli -h db01 -p 26379 Sentinel get-master-addr-by-name mymaster
redis-cli -h db02 -p 26379 Sentinel get-master-addr-by-name mymaster
redis-cli -h db03 -p 26379 Sentinel get-master-addr-by-name mymaster

8.模拟故障转移

关闭主节点服务上的所有redis进程

kill redis
  • 观察其他2个节点会不会发生选举
  • 查看配置文件里会不会自动更新
  • 查看新的主节点能不能写入
  • 查看从节点能否正常同步

9.模拟故障修复上线

启动单节点

redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf 

启动哨兵

redis-sentinel /opt/redis_cluster/redis_26379/conf/redis_26379.conf

10.模拟权重选举

设置其他节点的权重为0

redis-cli -h db02 -p 6379 CONFIG SET slave-priority 0
redis-cli -h db03 -p 6379 CONFIG SET slave-priority 0

手动发起重新选举

redis-cli -h db01 -p 26379 sentinel failover mymaster
  • 观察所有节点消息是否同步
  • 观察切换结果是否符合预期

验证选举结果:

redis-cli -h db01 -p 26379 Sentinel get-master-addr-by-name mymaster

命令解释:
1.查询命令:CONFIG GET slave-priority
2.设置命令:CONFIG SET slave-priority 0
3.主动切换:sentinel failover mymaster

操作命令:
redis-cli -h db02 -p 6379 CONFIG SET slave-priority 0
redis-cli -h db03 -p 6379 CONFIG SET slave-priority 0
redis-cli -h db01 -p 26379 sentinel failover mymaster

禁用危险指令:

设置配置文件

[root@db01 ~]# vim /opt/redis_cluster/redis_6379/conf/redis_6379.conf
rename-command KEYS ""

重启redis

[root@db01 ~]# redis-cli -h db01 shutdown
[root@db01 ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf

验证是否禁用

[root@db01 ~]# redis-cli -h db01
db01:6379> keys *
(error) ERR unknown command ‘keys‘

















































































































































































以上是关于总是听说很多javaweb系统用redis或memcache做缓存,具体怎么操作的的主要内容,如果未能解决你的问题,请参考以下文章

JavaWeb项目架构之Redis分布式日志队列

为啥Android中的文件'/sys/power/state'总是'mem'?

JavaWeb项目架构之Redis分布式日志队列-SpringBoot实例

使用memcache或redis限制某个用户或者某ip用户一段时间内最大投票次数

redis怎么进行内存管理?

Redis内存碎片深入分析