https://gitlab.com/zhangxin1932/java-tools.git (java-tools for redis5.0)
1.NoSql概述
类型 | 部分代表 | 特点 |
---|---|---|
列存储 | Hbase, Cassandra, Hypertable | 顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。 |
文档存储 | MongoDB, CouchDB | 文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。 |
key-value存储 | Berkeley DB, MemcacheDB, Redis | 可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收。(Redis包含了其他功能) |
图存储 | Neo4J, FlockDB | 图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便。 |
对象存储 | db4o, Versant | 通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。 |
xml数据库 | Berkeley DB XML, BaseX | 高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath。 |
CAP定理(CAP theorem)
在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer's theorem),
它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
//一致性(Consistency) (所有节点在同一时间具有相同的数据)
//可用性(Availability) (保证每个请求不管成功或者失败都有响应)
//分区容错性(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)
#CAP理论的核心是:
一个分布式系统不可能同时很好的满足一致性,
可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
因此,根据 CAP 原理将 NoSQL 数据库分成了
满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:
CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。
AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
BASE
BASE:Basically Available, Soft-state, Eventually Consistent。
CAP理论的核心是:
一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
BASE是NoSQL数据库通常对可用性及一致性的弱要求原则:
-Basically Availble --基本可用
-Soft-state --软状态/柔性事务。 "Soft state" 可以理解为"无连接"的, 而 "Hard state" 是"面向连接"的
-Eventual Consistency -- 最终一致性, 也是 ACID 的最终目的。
2.Redis 概述
2.1 Redis 历史
Redis3.0版本之前, 多采用哨兵模式搭建,
redis3.0以前有哨兵模式的配置模式(解决单点故障问题)
Redis3.0版本之后支持Cluster,使用ruby方式创建集群;
redis3.0开始支持集群(解决分布式中单点故障问题)
redis4.0开始支持AOF和RDB混合配置模式(解决数据持久化的问题)
2018年10月Redis发布了5.0版本,
新版本放弃了Ruby的集群方式,改为使用C语言编写的redis-cli的方式,
使集群的构建方式复杂度大大降低,本文介绍5.0版本集群的搭建。
2.2 Redis配置文件--redis.conf (Redis5.0为例)
1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
daemonize no
2. 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定
pidfile /var/run/redis.pid
3. 指定Redis监听端口,默认端口为6379,作者在自己的一篇博文中解释了为什么选用6379作为默认端口,因为6379在手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字
port 6379
4. 绑定的主机地址
bind 127.0.0.1
5.当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
timeout 300
6. 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
loglevel verbose
7. 日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null
logfile stdout
8. 设置数据库的数量,默认数据库为0,可以使用SELECT <dbid>命令在连接上指定数据库id
databases 16
9. 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
save <seconds> <changes>
Redis默认配置文件中提供了三个条件:
save 900 1
save 300 10
save 60 10000
分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。
10. 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
rdbcompression yes
11. 指定本地数据库文件名,默认值为dump.rdb
dbfilename dump.rdb
12. 指定本地数据库存放目录("修改成绝对路径")
dir ./
13. 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
slaveof <masterip> <masterport>
14. 当master服务设置了密码保护时,slav服务连接master的密码
masterauth <master-password>
15. 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭
requirepass foobared
16. 设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息
maxclients 128
(设置redis同时可以与多少个客户端进行连接。默认情况下为10000个客户端。当你无法设置进程文件句柄限制时,redis会设置为当前的文件句柄限制值减去32,因为redis会为自身内部处理逻辑留一些句柄出来。如果达到了此限制,redis则会拒绝新的连接请求,并且向这些连接请求方发出“max number of clients reached”以作回应。)
17. 指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区
maxmemory <bytes> # 建议设置为内存的2/3即可
(设置redis可以使用的内存量。一旦到达内存使用上限,redis将会试图移除内部数据,移除规则可以通过maxmemory-policy来指定。如果redis无法根据移除规则来移除内存中的数据,或者设置了“不允许移除”,那么redis则会针对那些需要申请内存的指令返回错误信息,比如SET、LPUSH等。)
(但是对于无内存申请的指令,仍然会正常响应,比如GET等。如果你的redis是主redis(说明你的redis有从redis),那么在设置内存使用上限时,需要在系统中留出一些内存空间给同步队列缓存,只有在你设置的是“不移除”的情况下,才不用考虑这个因素)
**maxmemory-policy**
(1)volatile-lru:使用LRU算法移除key,只对设置了过期时间的键
(2)allkeys-lru:使用LRU算法移除key
(3)volatile-random:在过期集合中移除随机的key,只对设置了过期时间的键
(4)allkeys-random:移除随机的key
(5)volatile-ttl:移除那些TTL值最小的key,即那些最近要过期的key
(6)noeviction:不进行移除。针对写操作,只是返回错误信息
**maxmemory-samples**
(设置样本数量,LRU算法和最小TTL算法都并非是精确的算法,而是估算值,所以你可以设置样本的大小,redis默认会检查这么多个key并选择其中LRU的那个)
18. 指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no
appendonly no
19. 指定更新日志文件名,默认为appendonly.aof
appendfilename appendonly.aof
20. 指定更新日志条件,共有3个可选值:
no:表示等操作系统进行数据缓存同步到磁盘(快)
always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
everysec:表示每秒同步一次(折衷,默认值)
appendfsync everysec
21. 指定是否启用虚拟内存机制,默认值为no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析Redis的VM机制)
vm-enabled no
22. 虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享
vm-swap-file /tmp/redis.swap
23. 将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0
vm-max-memory 0
24. Redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但一个page上不能被多个对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认值
vm-page-size 32
25. 设置swap文件中的page数量,由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,在磁盘上每8个pages将消耗1byte的内存。
vm-pages 134217728
26. 设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4
vm-max-threads 4
27. 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启
glueoutputbuf yes
28. 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法
hash-max-zipmap-entries 64
hash-max-zipmap-value 512
29. 指定是否激活重置哈希,默认为开启(后面在介绍Redis的哈希算法时具体介绍)
activerehashing yes
30. 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
include /path/to/local.conf
31.设置访问密码
# 当master服务设置了密码保护时,slav服务连接master的密码
# 下文的“requirepass”配置项可以指定密码
# masterauth <master-password>
# 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过auth <password>命令提供密码,默认关闭
# requirepass foobared
32.units
# Note on units: when memory size is needed, it is possible to specifiy
# it in the usual form of 1k 5GB 4M and so forth:
#
# 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes
#
# units are case insensitive so 1GB 1Gb 1gB are all the same.
3.Redis 安装 (Linux下, Redis5.0)
3.1 Redis集群模式安装
3.1.1 基本环境准备(三台机器)
yum install gcc -y
yum install gcc-c++ -y
sudo iptables -F # 关闭虚拟机防火墙
3.1.2 redis下载,编译,安装(三台机器)
cd /home
wget http://download.redis.io/releases/redis-5.0.0.tar.gz
tar -zxf redis-5.0.0.tar.gz
cd /home/redis-5.0.0
make && make PREFIX=/opt/redis install
#如果编译时报错:error “Newer version of jemalloc required”,解决办法为:
make MALLOC=libc
3.1.3 修改配置文件(三台机器)
在node01/node02/node03上创建目录
mkdir -p /home/redis-5.0.0/redis_cluster/7001
mkdir -p /home/redis-5.0.0/redis_cluster/7002
vi命令创建redis.conf并编辑(注意各机器的ip及port要修改)
vi /home/redis-5.0.0/redis_cluster/7001/redis.conf
# 绑定服务器IP地址
bind 192.168.0.199 #或192.168.0.198, 或192.168.0.197
# 绑定端口号,必须修改,以此来区分Redis实例
port 7001 #或7002
# 后台运行
daemonize yes
# 修改pid进程文件名,以端口号命名
pidfile /var/run/redis-7001.pid
# 修改日志文件名称,以端口号为目录来区分
logfile /home/redis-5.0.0/redis_cluster/7001/redis.log
# 修改数据文件存放地址,以端口号为目录名来区分
dir /home/redis-5.0.0/redis_cluster/7001/
# 启用集群
cluster-enabled yes
# 配置每个节点的配置文件,同样以端口号为名称
cluster-config-file nodes-7001.conf
# 配置集群节点的超时时间,可改可不改
cluster-node-timeout 15000
# 启动AOF增量持久化策略
appendonly yes
# 发生改变就记录日志
appendfsync always
3.1.4 配置各节点环境变量(三台机器)
vi /etc/profile
export REDIS_HOME=/opt/redis
export PATH=$REDIS_HOME/bin:$PATH
source一下配置文件, 使修改生效
source /etc/profile
3.1.5 启动各节点(三台机器)
redis-server /home/redis-5.0.0/redis_cluster/7001/redis.conf
redis-server /home/redis-5.0.0/redis_cluster/7002/redis.conf
查看是否启动成功
ps -ef | grep redis
各台机器上启动成功的话, 应该是下述格式
[root@localhost 7001]# ps -ef | grep redis
root 86689 1 0 11:29 ? 00:00:00 redis-server 192.168.0.199:7001 [cluster]
root 86879 1 2 11:32 ? 00:00:00 redis-server 192.168.0.199:7002 [cluster]
root 86887 79704 0 11:32 pts/0 00:00:00 grep --color=auto redis
3.1.6 使用 reids-cli 搭建 Redis集群
–cluster-replicas 1 ---> 命令的意思: 一主一从配置,六个节点就是 三主三从
redis-cli --cluster create 192.168.0.199:7001 192.168.0.198:7001 192.168.0.197:7001 192.168.0.199:7002 192.168.0.198:7002 192.168.0.197:7002 --cluster-replicas 1
使用如下命令检查集群的状态
redis-cli --cluster check 192.168.0.199:7001 #填写任意节点即可,会带出所有的
结果如下
[root@localhost 7001]# redis-cli --cluster check 192.168.0.199:7001
192.168.0.199:7001 (df0710cb...) -> 0 keys | 5461 slots | 1 slaves.
192.168.0.198:7001 (7193ccf2...) -> 0 keys | 5462 slots | 1 slaves.
192.168.0.197:7001 (0fcc2a4a...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.0.199:7001)
M: df0710cb8243197984d2eb0996da75cc723ef99a 192.168.0.199:7001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 44107c4b32c16f9dfaaf89d93968be87fca645bb 192.168.0.199:7002
slots: (0 slots) slave
replicates 0fcc2a4acf08b46bdc52a69e8117f959c275c91b
S: 5b32ccea4fc9837ab6556880be5f4d47440eaee6 192.168.0.198:7002
slots: (0 slots) slave
replicates df0710cb8243197984d2eb0996da75cc723ef99a
S: 3a787d7396cbc4f980c2bb2273d9326c99249885 192.168.0.197:7002
slots: (0 slots) slave
replicates 7193ccf25a491b42a43c8a5df028de38c4277199
M: 7193ccf25a491b42a43c8a5df028de38c4277199 192.168.0.198:7001
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 0fcc2a4acf08b46bdc52a69e8117f959c275c91b 192.168.0.197:7001
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
3.1.7 测试集群
redis-cli -c -h 192.168.0.199 -p 7002
[root@localhost 7001]# redis-cli -c -h 192.168.0.199 -p 7002
192.168.0.199:7002> set cat_name tom199
-> Redirected to slot [11238] located at 192.168.0.197:7001
OK
192.168.0.197:7001> get cat_name
"tom199"
192.168.0.197:7001> set dog_name jiaozi
-> Redirected to slot [2578] located at 192.168.0.199:7001
OK
192.168.0.199:7001> get dog_name
"jiaozi"
192.168.0.199:7001> exit
[root@localhost 7001]#
3.1.8 Redis启动与关闭命令
#server启动:
./redis-server --configurekey1 configurevalue1,一般来说 ./redis-server redis.conf来启动
#client启动:
./redis-cli -h host -p port
#server关闭:
./redis-cli shutdown [nosave|save](这种方式是比较优雅的关闭Redis server)
如: bin/redis-cli -p 26381 shutdown
3.2 Redis单机版搭建
3.2.3 修改配置文件
bind 0.0.0.0
port 26379
daemonize yes
pidfile /home/zhangxin/software/redis/install-prefix-redis/redis_26379.pid
logfile /home/zhangxin/software/redis/install-prefix-redis/redis_26379.log
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /home/zhangxin/software/redis/install-prefix-redis/
appendonly yes
appendfilename "appendonly.aof"
3.3 Redis主从模式 & 哨兵搭建
在某一台机器上安装完 redis 后. 创建几个文件夹
mkdir 26380 (主)
mkdir 26381 (从1)
mkdir 26382 (从2)
#若不需要哨兵模式, 下述关于哨兵的流程可不执行
mkdir 26383 (哨兵)
3.3.1 主配置
bind 0.0.0.0 #任意ip都可以连接
port 26380 #端口
daemonize yes #后台运行
pidfile /home/zhangxin/software/redis/install-prefix-redis/26380/redis_26380.pid #进程守护文件,就是存放该进程号相关信息的地方
logfile /home/zhangxin/software/redis/install-prefix-redis/26380/redis_26380.log #日志文件
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /home/zhangxin/software/redis/install-prefix-redis/26380/ #db等相关目录位置
appendonly yes
appendfilename "appendonly.aof"
3.3.2 从配置
vi 26381/redis.conf
bind 0.0.0.0 #任意ip都可以连接
port 26381 #端口号
slaveof 192.168.0.199 26380 #主信息
daemonize yes #后台运行
pidfile /home/zhangxin/software/redis/install-prefix-redis/26381/redis_26381.pid #进程守护文件,就是存放该进程号相关信息的地方
logfile /home/zhangxin/software/redis/install-prefix-redis/26381/redis_26381.log #日志文件
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /home/zhangxin/software/redis/install-prefix-redis/26381/ #db等相关目录位置
appendonly yes
appendfilename "appendonly.aof"
vi 26382/redis.conf
将上文中的 26381 全部改为 26382 即可
3.3.3 哨兵配置
可以看下是否可以一组哨兵监控多个业务的主从redis
vi 26383/sentinel.conf
bind 0.0.0.0 #允许任意 ip
port 26383 #端口号
daemonize yes #后台运行
pidfile /home/zhangxin/software/redis/install-prefix-redis/26383/redis_26383.pid #进程守护文件,就是存放该进程号相关信息的地方
logfile /home/zhangxin/software/redis/install-prefix-redis/26383/redis_26383.log #日志文件
dir /home/zhangxin/software/redis/install-prefix-redis/26383/ #db等相关目录位置
sentinel monitor mymaster 192.168.0.199 26380 1 #设置 主名称 ip地址 端口号 参入选举的哨兵数
sentinel down-after-milliseconds mymaster 3000 #sentinel心跳检测主3秒内无响应,视为挂掉,开始切换其他从为主
sentinel parallel-syncs mymaster 1 #每次最多可以有1个从同步主。一个从同步结束,另一个从开始同步。
sentinel failover-timeout mymaster 18000 #主从切换超时时间
3.3.4 依次启动主, 从1, 从2, 哨兵1
#启动主
bin/redis-server 26380/redis.conf
#启动从1
bin/redis-server 26381/redis.conf
#启动从2
bin/redis-server 26382/redis.conf
#启动哨兵1
bin/redis-sentinel 26383/sentinel.conf
3.3.5 查看启动情况
查看主从情况
[zhangxin@JD install-prefix-redis]$ bin/redis-cli -p 26380
127.0.0.1:26380> info
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.0.199,port=26381,state=online,offset=126,lag=0
slave1:ip=192.168.0.199,port=26382,state=online,offset=126,lag=1
master_replid:bd8c3f99be1ed9fb53af5dde225a5da21fca6cb8
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:126
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:126
查看哨兵监控情况
[zhangxin@JD install-prefix-redis]$ bin/redis-cli -p 26383
127.0.0.1:26383> info
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.0.199:26380,slaves=2,sentinels=1
3.3.6 关闭主26380, 此时查看, 发现26382 被选举为新的主
[zhangxin@JD install-prefix-redis]$ bin/redis-cli -p 26380 shutdown
[zhangxin@JD install-prefix-redis]$ bin/redis-cli -p 26383 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.0.199:26382,slaves=2,sentinels=1
3.3.7 重启26380, 此时查看, 发现26380成为26382的从
[zhangxin@JD install-prefix-redis]$ bin/redis-server 26380/redis.conf
[zhangxin@JD install-prefix-redis]$ bin/redis-cli -p 26382 info Replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.0.199,port=26381,state=online,offset=86290,lag=1
slave1:ip=192.168.0.199,port=26380,state=online,offset=86149,lag=1
master_replid:528cd5c6bcec2e39bdc66a2b1460a05fd59221b5
master_replid2:bd8c3f99be1ed9fb53af5dde225a5da21fca6cb8
master_repl_offset:86290
second_repl_offset:75023
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:86276
3.4 redis-gui安装
1.官方gui: redis-insight
2.其他民间gui: 可去github上搜索
参考资料
https://www.cnblogs.com/zwcry/p/9134721.html (Redis 哨兵模式搭建)
https://mp.weixin.qq.com/s?__biz=MzIwMTY0NDU3Nw==&mid=2651958642&idx=1&sn=a5fe8b65111b1eba475fa34e7d819ccb&chksm=8d0fc23cba784b2aa5365330f8e90e19784f5c8c685b5b272f4f69b9adda3ac1f51657a93a42&mpshare=1&scene=24&srcid=04015H1zU3lR1286IV3wtEkS&sharer_sharetime=1648771944632&sharer_shareid=9b286cadc70f5998699efc52a3cf3724#rd (redis-insight 安装)
https://blog.csdn.net/tiancityycf/article/details/123719904 (redis-insight 安装)