Centos7.6 使用docker安装redis简单入门
这里写自定义目录标题
1、为什么要用nosql(非关系型数据库)
- 易扩展性
- 大数据量下性能依然强悍
- NoSQL无需事先为要存储的数据建立字段,随时存储自定义的数据格式。
2、下载使用docker下载安装redis
#拉取镜像
docker pull redis
#在宿主机创建配置文件与,然后将你的redis配置文件放在这个创建的redis目录下
mkdir -p /usr/local/docker/redis
mkdir -p /usr/local/docker/redis/data
# 运行容器,映射6379端口,指定名称myredis ,配置容器卷-v,配置data目录,最后启动服务外加开启aop持久化
docker run -p 6379:6379 --name myredis -v /usr/local/docker/redis.redis.conf:/etc/redis/redis.conf -v /usr/local/docker/redis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes
3、查看默认redis安装目录
usr/local/bin 目录下
redis-benchmark:性能测试工具,可以测试读写速度
redis-check-aof:修复有问题的aof文件
redis-check-dump:修复有问题的dump.rdb文件
redis-cli:客户端,操作入口 # 例如 redis-cli -p 6379
redis-sentinel:redis集群使用
redis-server:Redis服务器启动命令 # 例如: redis-server /etc/redis/redis.conf
4、关闭当前redis-service 服务
单实例关闭:redis-cli shutdown
多实例关闭,指定端口关闭:redis-cli -p 6379 shutdown
5、redis基础知识
- 默认16个数据库,类似数组下表从零开始,初始默认使用零号库
- select命令切换数据库
- dbsize查看当前数据库的key的数量
- flushdb:清空当前库
- flushall;清空所有数据库
- 统一密码管理,16个库都是同样密码,要么都OK要么一个也连接不上
- Redis索引都是从零开始
6、redis中五大基本数据类型
- string 类型,一个redis中字符串value最多可以是512M
- hash类型,类似与java的Map
- list 类型 ,一个字符串列表,底层为链表结构
- set类型,redis的Set是string类型的无序集合。它是通过HashTable实现实现的,
- zset类型,与set的区别是:不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。
7、各种基本命令
7.1、key
- keys * :查询所有的key
- keys pattern(正则表达式) :查找匹配正则的key
- existx key的名字 : 判断当前key是否存在
- move key (数据库的序号) :将当前数据库的key移动到指定的数据库中,移完之后当前库就没了
- expire key (秒) :设置key的过期时间
- expire key (时间戳) :设置key的过期时间,输入时间戳
- ttl key :查看还有多长时间过期,单位为秒,-2代表已过期,-1代表永不过期
- type key :查看key的类型
- dump key :序列化给定key,并返回被序列化的值 (讲实话这个我不是很懂什么意思)
- randomkey : 从当前数据库中随机返回一个key
- rename oldkey newkey :修改oldkey的名称为newkey
- renamenx oldkey newkey:当newkey不存在时,将oldkey改名为newkey
7.2 、string
- set k1 v1 :存储一个字符串,key 为k1,value 为v1
- get k1:获取key为k1的值
- mget key1 key2 key3 :获取多个值
- mset k1 v1 k2 v2 :设置多个值
- msetnx k1 v1 k2 v2:设置多个值,仅当所有的key都不存在时
- getrange k1 0 2 : 获取下标0到2的值
- getrange k1 0 -1 :获取k1的全部值,-1表示到结尾
- getset key value :获取key的值,并将key重新赋值为value
- getbit key offset :对key所存储的字符串值,获取指定偏移量上的位(bit)
- setbit key offset value :对key所存储的字符串值,设置或清除指定偏移量上的位(bit)
- setex key seconds value :将值value关联给key,并且设置过期时间
- psetex key millseconds value :与setex相似,但是这里设置的过期时间为毫秒值
- setnx key value :当key不存在时,设置存储一个key value键值对
- setrange key offset value :从offset开始,设置key的值,会覆盖
- strlen key:得到key的长度
- incr key :将值加一,当前key比如为纯数字,不然运行时报错
- incrby key num :用num来指定key加几。
- incrbyfloat key increment :指定用来相加的浮点数
- decr key :将值减一
- decr key increment :指定减多少
- append key value:如果key已经存在并且是个字符串,会将value的值追加到原有的value中
7.3、list
- lpush key value1 从头部给key赋值,会设置一个类型为list key value,栈(先进后出)
- rpush key value1 从尾部为key赋值 , 队列(先进先出)
- lrange key 0 -1 获取list的所有值
- lpop key 移除并获取列表的第一个元素
- rpop key 移除并获取列表的最后一个元素
- lindex key index 根据index索引获得list的元素(从上到下)
- ltrim key 开始index 结束index : 截取指定范围内的值赋值重新赋值给key
- rpoppush list1 list2 : 将list1中的最后一个元素移到list2中,如果list2中已存在则无法传递 !!会添加到list2的头部,相当于lpush了过去
- lset key index value : 设置list中index索引所在内容的值为value
- linsert key after/before index value :在列表的元素前或者元素后插入元素,index为索引。
- rpushx key value : 为已有的列表添加值
- lrem key count value :移除列表元素,移除key中的count个数的value元素
- llen key :获取列表的长度
7.4、set 无序
- sadd key value1 value2 :向集合中添加多个元素
- smembers key 获取集合中所有成员
- sismember key number : 判断number是否是集合key的成员
- scard key :获取集合的成员数
- srem key value1 value2 :删除集合中的1个或者多个元素
- srandmember key count :随机返回集合中count个随机数
- spop key :随机出栈一个,并且返回出栈的成员
- smove key1 key2 在key1里的某个值:将key1中的某个值移动到key2中,key1就没有了
- sdiff key1 key2 key3 :返回指定集合的所有差集,当然,主要是看第一个
- sinter key1 key2 key3 : 返回指定集合的所有交集,也主要是看第一个
- sunion key1 key2 :返回指定集合的所有并集,也主要是看第一个
7.5、hash
- hset hash1 k1 v1 : 创建一个hash
- hget hash1 k1:获取hash1中的k1,这里将得到v1
- hmset hash2 k1 v1 k2 v2 :可以指定多个值
- hmget hash2 k1 k2 :可以得到多个值,这里为v1 v2
- hdel key k1 k2 :删除多个哈希表字段
- hlen key :获取哈希表中字段的数量
- hkeys key:获取哈希表中的所有字段名
- hvals key : 获取哈希表中所有字段的value值
- hincrby key 字段名 number : 为哈希表中的字段进行数学相加,相加值为number
- hincrbyfloat key 字段名 number : 为哈希表中的字段进行数学相加,相加值为number
- 以上还有两个对应的相减方法
- hsetnx hash1 k1 44 :如何不存在k1字段,则添加上k1字段赋值为44
7.6、zset (sorted set)有序,每个值多了个 分数(score)
- zadd zset1 10 v1 30 v2 40 v3 :创建个zset赋值3个值,一个10分的v1,以此类推
- zrange key 0 -1 withscores: 获取zset集合的全部值,带上分数返回
- zrangebyscore key 开始分 结束分 withscores : 获取zset集合开始分到结束分之间的值,带分数
- zrangebyscore key (开始分 结束分 withscores :加了(左小括号代表不包含开始分
- zcount key min max : 计算在有序集合中指定区间分数的成员数量
- zrank key value : 返回集合中指定成员的索引
- zreverank key value:返回集合中指定成员的索引(倒叙)
- zrevrange key 0 -1 :同zrange,只不过倒叙
- zrevrangebyscore key 开始分 结束分 :同zrangebyscore ,但是这是倒叙
8、redis的配置文件redis.conf
8.1 通用配置 general
- daemonize :是否为守护进程(即后台进程),默认为false
- pidfile :当redis作为守护进程运行的时候,它会把 pid 默认写到 /var/run/redis.pid 文件里面,可以指定它的文件位置。
- port : 配置开放服务的端口
- tcp-backlog :tcp监听的最大数量,backlog其实是一个连接队列,backlog队列总和=未完成三次握手队列 + 已经完成三次握手队列。在高并发环境下你需要一个高backlog值来避免慢客户端连接问题。注意Linux内核会将这个值减小到/proc/sys/net/core/somaxconn的值,所以需要确认增大somaxconn和tcp_max_syn_backlog两个值
- timeout :指定在一个客户端连接多少秒超时,超时会断开(0 就是永不超时)
- bind : 绑定端口,多个端口之间用空格分割。就是只有绑定的ip的能够连接,可以注释掉,表示所有ip都能连接
- tcp-keepalive:单位为秒,如果设置为0,则不会进行Keepalive检测,建议设置成60 ,可以理解为心跳检测,如果超时则使用 SO_KEEPALIVE 发送 tcp acks 给客户端。
- loglevel :日志级别,一般为notice, 一个4个 [debug,verbose,notice,warning];
- logfile :指定日志文件的位置,空字符串表示标准输出。注意如果redis配置为后台进程,标准输出中信息会发送到/dev/null,指定示例:/usr/local/redis/redis.log,如果不指定,默认不记录日志
- syslog-enabled:是否把redis的系统日志输出到syslog中,位置会存在于logfile指定的目录
- syslog-ident :指定syslog里的日志标识,如果syslog-enabled为false,那么此项形同虚设
- syslog-facility :指定syslog 设备(facility), 必须是USER或者LOCAL0到LOCAL7.
- databases :指定数据库数量。
8.2 snapshotting 快照配置 ,也就是持久化
- save
生产建议配置:
是1分钟内改了1万次,
或5分钟内改了10次,
或15分钟内改了1次。
- stop-writes-on-b gsave-error:如果 redis 最后一次的后台保存失败,redis 将停止接受写操作, 让用户知道数据不能正确的持久化到磁盘,避免无人注意到。如果后台保存进程重新启动工作了,redis 也将自动的允许写操作。如果配置成no,表示你不在乎数据不一致或者有其他的手段发现和控制
- rdbcompress:对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用
LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能 - rdbchecksum:在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能
- dbfilename:存储的快照名称,一般默认即可
- dir:持久化备份文件目录
8.3 security安全
- redis默认登录无需密码,这里列一下查看,修改,以及取消密码的操作
查看: config get requirepass # 返回的结果: 1):“requirepass” 2):”“
修改:config set requirepass ”123123“ # 返回的结果: OK
取消:config set requirepass "" #返回的结果: OK
如果添加了密码之后,进行操作需要认证,认证指令为:auth 123123 (这里的123123指的是我设置的密码)
8.4 limits 限制
- maxclients : 支持最大同时连接的客户端,默认情况下为10000个客户端。当你无法设置进程文件句柄限制时,redis会设置为当前的文件句柄限制值减去32,因为redis会为自身内部处理逻辑留一些句柄出来。如果达到了此限制,redis则会拒绝新的连接请求,并且向这些连接请求方发出“max number of clients reached”以作回应。
- maxmemory:设置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:不进行移除。针对写操作,只是返回错误信息
简单说一下:lru指的是最近最少使用,最近最少使用的将会被置换 - maxmemory-samples : 在进行缓存的移除时,选取对应个数的样本进行清除。LRU算法和最小TTL算法都并非是精确的算法,而是估算值,所以你可以设置样本的大小,redis默认会检查这么多个key并选择其中LRU最小,也就是使用最少的几个为样本
8.5 append only mode 追加
- appendonly:是否开启aof 追加备份
- appendfilename :备份后的aof文件名称
- appendfsync:追加备份的规则
always:同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好
everysec:出厂默认推荐,异步操作,每秒记录 如果一秒内宕机,有数据丢失
no :不写入,不备份 - no-appendfsync-on-rewrite:重写时是否可以运用Appendfsync,用默认no即可,保证数据安全性。
- auto-aof-rewrite-min-size : 设置重写的基准值
- auto-aof-rewrite-percentage:设置重写的基准值
9、rdb持久化
9.1 简述
- 介绍:在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。
- 简述:Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
- fork:fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。
- 配置文件的位置与配置可以看上方配置文件中的 snapshotting(快照)。
9.2 基本rdb操作
- 如何触发rdb快照:
Save:save时只管保存,其它不管,全部阻塞。
BGSAVE:Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。可以通过lastsave命令获取最后一次成功执行快照的时间执行flushall命令,也会产生dump.rdb文件,但里面是空的,无意义 - 如何查看rdb存储路径。config get dir
- 动态停止所有rdb保存规则的方法:redis-cli config set save “”
9.3 优势和劣势
- 优势:适合大规模的数据恢复,将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可,对数据完整性和一致性要求不高
- 劣势:在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改,fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
10、append only file ,aof持久化
10.1 简介
- 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
- AOF保存的是appendonly.aof文件
10.2 aof的启动/修复/恢复
- 正常恢复:
启动:设置为yes,修改appendonly no 为 yes
恢复:将有数据的aof文件复制一份保存到对应目录(config get dir)恢复,重启redis会自动加载 - 异常恢复:
备份被写坏的AOF文件
恢复:redis-check-aof --fix (需要被修复的文件名)进行修复,重启redis重新加载
10.3 rewrite 重写
- 是什么: AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof
- 重写原理:AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似
- 触发机制:Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发
10.4 优势与劣势
- 优势:每修改同步:appendfsync always 同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好。每秒同步:appendfsync everysec 异步操作,每秒记录 如果一秒内宕机,有数据丢失。不同步:appendfsync no 从不同步
- 劣势:相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb。aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同。
11、对于持久化的总结
- RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储
- AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾。Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
- 只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式
- 同时开启两种持久化方式:
------在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整
------RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?
作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),
快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。 - 性能建议:
·······因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。
·······如果Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值。
·······如果不Enable AOF ,仅靠Master-Slave Replication 实现高可用性也可以。能省掉一大笔IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个。新浪微博就选用了这种架构
12、redis的事务 transaction
- 简介:
可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞 - 能干嘛:
一个队列中,一次性、顺序性、排他性的执行一系列命令 - 事务命令
watch key1 key2 :监听一个或者多个key,如果是事务执行前这些key被其他命令所改动,那么事务将会被打断。
multi :标记一个事务块的开始
exce:执行所有事务块内的命令
discard:取消事务,放弃执行事务块内的所有命令
unwatch:取消watch命令对所有key的监听
关于redis的事务:
······如果在使用multi开启了一个事务块后,执行的命令有在编译时报错,那么在使用exce执行的时候,会导致所有的事务块内的命令都执行不成功
······如果是一个在运行时才会保存,例如 incr key时,会将其他的事务提交,然后单独incr key执行不成功
12.1 watch监控
- WATCH之后有任何Key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回Nullmulti-bulk应答以通知调用者事务执行失败
- 特性:
1、单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
2、没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题
3、不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚
13、redis的发布订阅
13.1 是什么?
进程间的一种消息通信模式、发布者(pub)发送消息,订阅者(sub)接收消息
13.2 基础命令
- psubscribe pattern … :订阅一个或多个给定模式的频道 例如:psubscribe book*,表示订阅book开头的全部频道
- pubsub subcommand [argument…] :查看订阅与发布系统状态:pubsub greenbook
- publish clannel message : 将信息发送到指定的频道 :发送消息到指定频道 ,publish greenbook 绿色的书
- punsubscribe pattern … 退订所有给定模式的频道
- subscribe channel 订阅给定的一个躲着多个频道的信息
- unsubscribe channel 退订给定的频道
14、复制机制(主从复制)
14.1 是什么?
- 行话,也就是我们所说的主从复制,主机数据更新后立马同步到从机上。master 主机写为主,slave读为主
- 使用场景:读写分离,容灾恢复
14.2 使用方式
- 配从库不配主库
- 从库配置:可以在redis.conf 文件中找到slaveof属性,配置为 slaveof 主库ip 主库端口。这样启动后就会自动进行连接,成为从库。也可以在使用service-cli 连接后使用 slaveof 主库ip 主库端口,这种命令的方式配置,但是每次从机挂了都需要重新配置(不推荐)
- 查看当前服务的复制信息:
info replication
14.3 小细节
- 在一主二仆的关系中,如果主机挂了,那么从机会原地待命
- 如果从机挂了,不影响其他从机与主机间的通讯,如果这台挂了的从机配置了redis.conf配置文件中的slaveof,那么即可在重连后继续链接上主机
- 从机不进行写操作
- 如果主机设置了密码,那么从机需要知道密码,可以在redis.conf 文件中配置masterauth
几个小问题:
1 切入点问题?slave1、slave2是从头开始复制还是从切入点开始复制?比如从k4进来,那之前的123是否也可以复制
2 从机是否可以写?set可否?
3 主机shutdown后情况如何?从机是上位还是原地待命
4 主机又回来了后,主机新增记录,从机还能否顺利复制?
5 其中一台从机down后情况如何?依照原有它能跟上大部队吗?
- slave 之间不可不说的关系
上一个Slave可以是下一个slave的Master,Slave同样可以接收其他,slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻master的写压力。
中途变更转向:会清除之前的数据,重新建立拷贝最新的 - slaveof no one
使当前数据库停止与其他数据库的同步,转换成主数据库
14.4 复制原理
- slave启动成功连接到master后会发送一个sync命令
- Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步
- 全量复制:slave服务在接收到数据库文件数据后,将其存盘并加载到内存中
- 增量复制:master继续将新的所有收集到的修改命令依次传给slave,完成同步
- 但是只要是重新连接master,一次完成同步(全量复制)将被自动执行
14.5 哨兵模式(sentinel)
- 主要用于监听master主库,如果主库挂了,会根据投票数在剩下的从库中选举出一个作为master主库
- 创建一个sentinel.conf文件,名字绝对不能错
- 配置哨兵,填写内容:
sentinel monitor 被监控的数据库名字(名字自己取) ip号 端口号 3, - 上面这个3代表着,有3票就成为主机
- 启动哨兵:redis-sentinel /usr/local/docker/redis/sentinel.conf (这里的目录按照自己的实际情况写)
- 这个时候如果master挂了,那么会重新选举一个master,然后之前的master重连后会成为新master的slave
14.6 复制的缺点
由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。
以上一些内容取自于尚硅谷周阳老师的redis课程,仅作参考学习