Linux 安装redis
安装Redis
下载Redis
- 官网下载:https://redis.io/download
wget http://download.redis.io/releases/redis-5.0.7.tar.gz
解压并安装Redis
- 解压:
tar -zxvf redis-5.0.7.tar.gz -C /opt/module/redis
- 编译:
cd /opt/module/redis/redis-5.0.7
make
- 安装:
make PREFIX=/opt/module/redis/redis-5.0.7 install
redis.conf 配置文件
- 命令查看redis配置:
./redis-cli
CONFIG GET *
- 常用配置项
配置项名称 | 配置项值范围 | 说明 |
---|---|---|
daemonize | yes、no | yes表示启用守护线程后台运行,默认no,该属性配置为yes |
port | 指定 Redis 监听端口,默认端口为 6379 | |
bind | 绑定的主机地址,如果需要设置远程访问则直接将这个属性备注下或者改为bind * 即可,这个属性和下面的protected-mode控制了是否可以远程访问 | |
protected-mode | yes、no | 保护模式,该模式控制外部网是否可以连接redis服务,默认是yes,所以默认我们外网是无法访问的,如需外网连接rendis服务则需要将此属性改为no |
timeout | 300 | 当客户端闲置多长时间后关闭连接,如果指定为 0,表示关闭该功能 |
loglevel | debug、verbose、notice、warning | 日志级别,默认为 notice |
databases | 16 | 设置数据库的数量,默认的数据库是0。整个通过客户端工具可以看得到 |
rdbcompression | yes、no | 指定存储至本地数据库时是否压缩数据,默认为 yes,Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变的巨大。 |
dbfilename | dump.rdb | 指定本地数据库文件名,默认值为 dump.rdb |
dir | 指定本地数据库存放目录 | |
requirepass | 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH 命令提供密码,默认关闭 | |
maxclients | 0 | 设置同一时间最大客户端连接数,默认无限制,Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息。 |
maxmemory | XX (bytes) | 指定 Redis 最大内存限制,Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis 新的 vm 机制,会把 Key 存放内存,Value 会存放在 swap 区。配置项值范围列里XXX为数值。 |
查看Redis
- 查看redis进程
ps -aux | grep redis
- 端口监听查看
netstat -lanp | grep 6379
启动Redis
bin/redis-server redis.conf
关闭Redis
redis开机自启
- 编写开机自启脚本
#!/bin/bash
#
# chkconfig: 2345 10 90
# description: Start and Stop redis
PATH=/usr/local/bin:/sbin:/usr/bin:/bin
REDISPORT=6379
EXEC=/opt/module/redis/redis-5.0.7/bin/redis-server
REDIS_CLI=/opt/module/redis/redis-5.0.7/bin/redis-cli
PIDFILE=/var/run/redis.pid
CONF="/opt/module/redis/redis-5.0.7/redis.conf"
AUTH="111111"
case "$1" in
start)
if [ -f $PIDFILE ]
then
echo "$PIDFILE exists, process is already running or crashed."
else
echo "Starting Redis server..."
$EXEC $CONF
fi
if [ "$?"="0" ]
then
echo "Redis is running..."
fi
;;
stop)
if [ ! -f $PIDFILE ]
then
echo "$PIDFILE exists, process is not running."
else
PID=$(cat $PIDFILE)
echo "Stopping..."
$REDIS_CLI -p $REDISPORT SHUTDOWN
sleep 2
while [ -x $PIDFILE ]
do
echo "Waiting for Redis to shutdown..."
sleep 1
done
echo "Redis stopped"
fi
;;
restart|force-reload)
${0} stop
${0} start
;;
*)
echo "Usage: /etc/init.d/redis {start|stop|restart|force-reload}" >&2
exit 1
esac
- 设置redis权限
chmod 755 /etc/init.d/redis
- 启动redis
/etc/init.d/redis start
- 设置开机启动
cd /etc/init.d/
chkconfig redis on
Redis高可用集群安装
redis集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。不需要sentinel哨兵也能完成节点移除和故障转移的功能,需要将每个节点设置成集群模式。
- 安装gcc:
yum install gcc
- 下载安装:https://redis.io/download
- 编译:
make & make install
- 在/opt/module/redis/下创建redis-cluster,分别创建 8001 8004文件夹
- copy redis.conf 到8001,修改如下内容
(1)daemonize yes
(2)port 8001(分别对每个机器的端口号进行设置)
(3)dir /opt/module/redis/redis-cluster/8001/(指定数据文件存放位置,必须要指定不同的目 录位置,不然会丢失数据)
(4)cluster-enabled yes(启动集群模式)
(5)cluster-config-file nodes-8001.conf(集群节点信息文件,这里800x最好和port对 应上)
(6)cluster-node-timeout 5000
(7)# bind 127.0.0.1(去掉bind绑定访问ip信息)
(8)protected-mode no (关闭保护模式)
(9)appendonly yes 如果要设置密码需要增加如下配置:
(10)requirepass zhuge (设置redis访问密码)
(11)masterauth zhuge (设置集群节点间访问密码,跟上面一致)
- 把修改后的配置文件copy到 8004,修改2、3、5项里面的端口号
- 另外两台机器也做上面几步操作,第二台用 8002、8005,第三台用 8003、8006
- 分别启动6个redis实例:
/opt/module/redis/redis-6.2.5/src/redis-server /opt/module/redis/redis-cluster/800*/redis.conf
- 查看是否启动成功:
ps -ef | grep redis
- 用 redis-cli创建整个redis集群
/opt/module/redis/redis-6.2.5/src/redis-cli -a cmlx1218 --cluster create --cluster-replicas 1 192.168.10.101:8001
192.168.10.102:8002 192.168.10.103:8003 192.168.10.101:8004 192.168.10.102:8005 192.168.10.103:8006
- 验证集群
(1) 连接任意一个客户端:/opt/module/redis/redis-6.2.5/src/redis-cli -c -h 192.168.10.101 -p 8001 -a cmlx1218
(2) 进行验证:cluster info(查看集群信息)、cluster nodes(查看节点列表)
Redis的相关应用
1、string (字符串)
- setnx key value
如果key不存在执行 set 创建并返回1,如果存在返回0,可以根据这个特性做redis的分布式锁
在实际运用中,可以给该key设置一个过期时间,防止逻辑出错该锁一直存在造成死锁
- 原子计数
如果value是一个整数,可以进行自增自减操作(incr、incrby、decr、decrby),同样可以用来做分布式锁
同时几个线程incr 该lock时,获取到值为1的就算拿到了该锁,然后每个线程都要decr该 锁,保证最终lock的值为0
- 和java中原子操作的原理不同,java中利用了cas的原理而redis是利用单线程
- redis是单线程异步IO
2、list (列表)
Redis的列表类似Java中的linkedList,是链表不是数组,插入和删除速度很快 时间复杂度 O(1),索引定位很慢 时间复杂度为O(n)。
当列表弹出最后一个元素之后,该数据结构被自动删除,内存被回收。
Redis 的列表结构常用来做异步队列使用,将需要延后处理的任务结构体序列化成字符串塞进Redis的列表,另一个线程从这个列表中轮循数据进行处理
3、hash(字典)
Redis的字典类似Java中的HashMap,数组+链表二维结构。第一维的数组位置碰撞时就会将元素使用链表串接起来。
一般用来存储用户信息,可以部分获取,不想字符串只能一次性全部获取。但是hash结构的存储消耗高于单个字符串。
4、set(集合)
Redis 的集合相当于 Java 语言里面的 HashSet,它内部的键值对是无序的唯一的。它的内部实现相当于一个特殊的字典,
字典中所有的 value 都是一个值NULL。 当集合中最后一个元素移除之后,数据结构自动删除,内存被回收。
5、zset(有序集合)
zset 似于 Java 的 SortedSet 和 HashMap 的结合体,一方面它是一个 set,保证了内部 value 的唯一性,
另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权重。
其他
- Redis 单线程为什么还能这么快?
因为所有数组都在内存中,所有运算都是内存级别的运算,而且单线程避免了多线程切换性能的损耗。
正因为是单线程所以需要谨慎使用耗时的指令(keys等)
- Redis 单线程如何处理那么多的并发客户端连接?
Redis的 IO多路复用:redis 利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,
事件分派器将事件分发给事件处理器。Nginx也是采用IO多路复用原理解决 C10K问题
持久化
- RDB快照(snapshot)
默认将内存数据库快照保存在名字为 dump.rdb的二进制文件中
可以设置 "N秒内有至少M个改动"这一条件满足时,自动保存一次数据集。
save 60 1000 -> 满足"60 秒内有至少有 1000 个键被改动"这一条件时, 自动保存一次数据集
- AOF(append-only file)
快照功能并不是非常耐久(durable): 如果Redis故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据
通过修改配置文件来打开 AOF 功能 -> (appendonly yes)
- 混合持久化
AOF在重写时将重写这一刻之前的内存rdb快照文件的内容和增量的 AOF修改内存数据的命令日志文件存在一起,都写入新的aof文件,
新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换
开启混合持久化 -> (aof-use-rdb-preamble yes)
缓存淘汰策略
当 redis 内存超出屋里内存限制时,内存的数据会开始和磁盘产生频繁的交换(swap),交换会让redis的性能急剧下降
为了限制最大使用内存,Redis提供配置参数(maxmemory)来限制内存超出期望大小。
当实际内存超出 maxmemory 时,Redis提供几种策略(maxmemory-policy)来让用户自己决定该如何腾出新的空间以继续提供读写服务
- noeviction:默认的淘汰策略。不会继续服务写请求(DEL请求可以继续服务),读请求可以继续进行。这样可以保证不会丢失数据,但是会让线上的业务不能持续进行
- volatile-lru:尝试淘汰设置了过期时间的key,最少使用的key优先被淘汰,没有设置过期时间的key不会被淘汰
- volatile-ttl:ttl越小越优先被淘汰
- volatile-random:淘汰的key是过期key集合中随机的
- allkeys-lru:淘汰所有key,优先淘汰使用最少的key
- allkeys-random:随机淘汰所有的key
SpringBoot 整合 redis集群
#redis相关配置
spring:
redis:
session:
enabled: true
packages-to-scan: "com.cmlx"
expired-time: 3600
page-size: 20
# host: "10.0.1.13"
cluster:
nodes: 192.168.10.101:8001,192.168.10.102:8002,192.168.10.103:8003,192.168.10.101:8004,192.168.10.102:8005,192.168.10.103:8006
port: 6379
database: 1
lettuce:
pool:
max-active: -1
min-idle: 100
max-idle: 100
max-wait: 1000
password: "cmlx1218"
timeout: 10000