通过阅读redis官方文档,得知输入以下命令直接把文件下载到你当前所在目录中
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
tar xzf redis-5.0.5.tar.gz
cd redis-5.0.5
make
编译二进制文件。
对redis进行make编译之后会出现的。
之后输入以下命令进入src目录:
cd src
redis-server:用于启动redis服务的脚本文件
redis-cli:是终端控制脚本
redis-benchmark:用来进行压力测试的脚本文件
redis-check-aof、redis-check-dump:检测备份文件的脚本文件
在/usr/loacl目录下创建redis目录输入以下命令
mkdir /usr/local/redis
##### 3、将redis-server和redis-cli文件拷贝到刚刚创建的文件夹下
在 …/redis-5.0.5/src下输入以下命令
cp redis-server redis-cli /usr/local/redis
再redis安装目录下输入以下命令:
cp redis.conf /usr/local/redis
需要使用后台打开配置文件。
在刚刚创建的redis启动目录中打开编辑redis.conf文件,修改配置文件。
将daemonize的选项改为yes,设置后台启动redis。
再次启动redis服务,并使用刚刚编辑的配置文件,输入以下命令:
./redis-server redis.conf
便可完成。
后台启动redis服务,可以输入ps -e|grep redis查看进程。
能看到redis-server服务开启了。
在/usr/local/redis文件下输入以下命令,进入redis终端。
./redis-cli
在redis中,除了“\n”和空格不能作为名字的组成内容外,其他内容都可以作为key的名字部分,名字长度不做要求。
keys键操作:
key名 | 用法 |
---|---|
existis key | 测试指定key是否存在 |
del key1 key2 | 删除给定key |
type key | 返回给定key的value类型 |
keys pattern | 返回皮牌指定模式的所有key |
rename aldkey newkey | 改名字 |
dbsize | 返回当前数据库的key数量 |
expire key seconds | key指定过期时间 |
ttl key | 返回key的剩余过期秒数 |
select db-index | 选择数据库 |
move key db-index | 将key从当前数据库移动到指定数据库 |
flushdb | 删除当前数据库中所有key |
flushall | 删除所有数据库中的所有key |
Key:
给存储在redis内存zhong 的数据起的变量名字
Values
Strings
List
Sets
Sirted sets
Hash
默认可以使用16个数据库。
key | 用法 |
---|---|
set key value | 设置key对应的值为string类型的value |
mset key1 value 1 —keyN valueN | 一次性设置多个key的值 |
mget key1 key2 —keyN | 一次性获取多个key的值 |
incr key | 对key的值做加加操作,并返回新的值 |
decr key | 同上,但是做的事减减操作 |
incrby key integer | 同incr,加指定值 |
decrby key integer | 同decr,减指定值 |
substr key start end | 返回截取的key的字符串值 |
incr | 该指令可以对与key进行累加操作 |
命令名 | 作用 |
---|---|
dbsize | 查看当前所在数据库中有多少key |
keys * | 查看当前所在数据库中所有key(在实际应用中最好不要使用) |
flashall | 清楚所有数据库中的所有key-value |
flashdb | 清除当前数据库中的所有key-value |
exlsts | 查看是否存在这个key |
可以通过该配置项修改,使用yes启用守护进程,设置以下属性:
daemonize no
运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定:
pidfile /var/run/redis.pid
默认端口为6379,作者在自己的一篇博文中解释了为什么选用6379作为默认端口,因为6379在手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字。
port 6379
bind 127.0.0.1
如果指定为0,表示关闭该功能。
timeout 300
Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose。
loglevel verbose
默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null
logfile stdout
默认数据库为0,可以使用SELECT 命令在连接上指定数据库id
databases 16
就将数据同步到数据文件,可以多个条件配合
save
Redis默认配置文件中提供了三个条件:
save 900 1
save 300 10
save 60 10000
分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。
默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
rdbcompression yes
dbfilename dump.rdb
dir ./
slaveof
masterauth
如果配置了连接密码,客户端在连接Redis时需要通过AUTH 命令提供密码,默认关闭。
requirepass foobared
默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息。
maxclients 128
Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区。
maxmemory
Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no。
appendonly no
appendfilename appendonly.aof
no:表示等操作系统进行数据缓存同步到磁盘(快)
always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
everysec:表示每秒同步一次(折衷,默认值)
appendfsync everysec
默认值为no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析Redis的VM机制)。
vm-enabled no
默认值为/tmp/redis.swap,不可多个Redis实例共享。
vm-swap-file /tmp/redis.swap
无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0。
vm-max-memory 0
一个对象可以保存在多个page上面,但一个page上不能被多个对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认值。
vm-page-size 32
由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,在磁盘上每8个pages将消耗1byte的内存。
vm-pages 134217728
最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4。
vm-max-threads 4
是否把较小的包合并为一个包发送,默认为开启
glueoutputbuf yes
采用一种特殊的哈希算法。
hash-max-zipmap-entries 64
hash-max-zipmap-value 512
默认为开启(后面在介绍Redis的哈希算法时具体介绍)
activerehashing yes
可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
include /path/to/local.conf
redis默认索引开始从0开始
string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。
string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M。
Redis hash 是一个键值对集合。
Redis hash 是一个String类型的field和value的映射表,hash特别适合用于存储对象。
Redis List是简单的字符串列表,按照插入顺序排序,可以添加一个元素到列表的头部(左边)或者尾部(右边)。
底层通过链表实现。
Redis的set是string类型的无序集合。通过hash table实现。
Redis zset和set一样是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都回关联一个double类型的分数。
Redis正是通过分数为集合中的成员进行从大到小的排序。Zset的成员是唯一的,但是分数是可以重复的。
Exists key的名字,判断某个key是否存在。
将当前所在数据库移除。
查看你所指定的key还有多少秒过期。
Type key查看你的key是什么类型的。
(1)get key
get key获取key的值
(2)set key
set key 设置key的值
(3)del key
del key 删除key的值
(4)append
在尾部追加值
格式:
Append key值 追加的值
(5)strlen
strlen 返回键值的长度
格式:
strlen key值
(1) incr
incrby 递增整数值
格式:incr key值
(2) decr
decr 递减整数值
格式:decr key值
(3) incrby
incrby递增整数值,可指定增减的数值
格式:incrby key值 正负数
(4) decrby
decrby递减整数值,可指定增减的数值
格式:decrby key值 正负数
(1) getrange
getrange获取指定索引范围内的值。
格式:getrange key值 起始索引 结束索引。
(2) setrange
setrange设置指定索引范围的值。
格式:setrange key值 起始索引 结束索引。
(1) setex
setex设置带过期时间的key,动态设置。
格式:
setex键 秒值 真实值
(2) setnx
setnx只有在key不存在时设置key的值。
格式:
setnx键 秒值 真实值
(1) mset
mset同时设置多个键的值。
格式:
mset key值 value(key和value可以是多对)
(2) mget
mget同时获取多个键的值。
格式:
mget 多个key值
(3) msetnx
msetnx同时设置一个或多个key-value对,当且仅当所有给定key都不存在。
格式:
msetnx 多个key-value键值对
getset:原子的设置key的值,并返回key的旧值。
格式:
getset key value+
(1) lpush
lpush添加值
格式:
lpush list的key item项的值(值可能是多个)
(3) rpush
rpush添加值
格式:
rpush list的key item项的值(值可能是多个)
(4) lrange
lrange按索引范围获取值
格式:
lrange list的key 其实索引 终止索引(-1表示最后一个索引)
(1) lpop
lpop弹出值
格式:
lpop list的key
(2)rpop
rpop弹出值
格式:
rpop list的key
lindex获取指定索引的值
格式:
lindex list的key 索引号
llen获取list中元素的个数
格式:
llen list的key
lrem key删除N个value
格式:
lrem list的key 数量 item项的值
ltrim key截取指定范围的值后再复制给key
格式:
ltrim key 开始index 结束index,截取指定范围的值后再复制给key
rpoplpush移除列表的最后一个元素,并将该元素添加到另一个列表并返回
格式:
rpoplpush 源列表 目的列表
lset设置指定索引的值
格式:
lset list的key 索引 新值
Linsert插入元素
格式:
linsert list的key before|after 定位查找的值 添加的值
它是一个字符串链表,left、right都可以插入添加;
如果键不存在,创建新的链表;
如果键已存在,新增内容;
如果值全移除,对应的键也就消失了。
链表的操作无论是头和尾效率都极高,但假如是对中间元素进行操作,效率就很惨淡了。
(1)sadd
sadd添加元素。
格式:
sadd set的key item的项值,item项可以又多个
(2)smembers
Smembers:获取集合中所有元素。
格式:
smembers set的key
(3)sismember
Sismember:判断元素是否所在集合中。
Scard获取集合中元素的个数。
格式:
scard set的key
Srem删除元素。
格式:
srem set的key item项的值
Srandmember随机获取集合的元素。
格式:
srandmember set的key[数量]。(数量为正数时,会随机获取这么多个不重复的元素;如果数量大于集合元素个数,返回全部;如果数量为负,会随机获取这么多个元素,可能有重复。)
Spop:弹出元素。
格式:
spop set的key
Smvoe:将一个key值赋值给另一个key。
格式:
smove key1 key2
(1) hset
hset:设置值。
格式:
hset hash的key项的key项的值
(2) hget
hget:获取值。
格式:
hget hash的key项的key
(3) hmet
hmet::同时设置多对值。
格式:
hmet hash的key项的key项的值(项的key和项的值可以是多对)
(4) hgetall
hgetall:获取该key下所有的值。
格式:
hgetall hash的key
(5) hdel
hdel:删除某个项。
格式:
hdel hash的key项的key
hlen:获取key里面的键值对数量。
格式:
hlen hash的key
hexists key:判断键值对是够存在。
格式:
hexists hash的key项的key
(1) hkeys
hkeys:获取所有的item的key。
格式:
hkey hash的key
(2) hvals
hvals:获取所有的item的值。
格式:
hvals hash的key
(1) hincrby
hincrby:增减整数数字。
格式:
hincrby Hash的key项的key正负数
(2) hincrbyfloat
hincrbyfloat: 增减float数值。
格式:
hincrbyfloat Hash的key项的key正负float
(3) hsetnx
hsetnx:如果不存在则复制,存在时什么都不做。
格式:
hsetnx Hash的key项的key项的值
(1)zadd
zadd:添加元素。
格式:
zadd zset的key score值项的值,Source和项可以是多对,score可以是整数,也可以是浮点数,还可以是+inf表示无限大,-inf表示负无穷大
(2)zrange
zrange:获取索引区间内的元素。
格式:
zrange zset的key其实索引 终止索引(withscore)
zrangebyscore :获取分数区间内的元素。
格式:
zrangebyscore zset的key 起始score 终止score (withscore),默认是包含端点值的,如果加上"("表示不包含,后面还可以加上limit来限制。
zrem:删除元素。
格式:
zrem zset的key项的值,项的值可以是多个
(1)zcard
zcard:获取集合中元素个数。
格式:
zcard zset的key
(2)zcount
zcount:获取分数区间内元素个数。
格式:
zcount zset的key起始score终止score
zrevrank:获取项在zset中倒序的索引。
格式:
zrevrank zset的key项的值
zrevrange:获取索引区间内的元素。
格式:
zrevrange zset的key其实索引 终止索引 (withscores)
zrevrangebyscore:获取分数区间内的元素。
格式:
zrevrangebyscore zset的key 终止scroe 起始score(withscores)
1)定义
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话将的Snapshot快照,它恢复时时将快照文件直接读到内存里。
2)具体
Redis会单独创建(fork)一个子线程类进行持久化,会先将数据写入到一个临时文件中,待持久化过程结束了,再将这个临时文件替换上次持久化好的文件。整个过程中,主进程时不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
Fork的作用就是复制一个与当前线程一样的线程。新线程的所有数据(变量、环境变量、程序计数器等),数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。
(1) 配置文件中默认的快照配置
冷拷贝后重新使用,可以cp dump.rdb dump_new.rdb
(2) 命令save或者bgsave
1)Save
Save时只保管保存,其他不管,全部阻塞
2)bgsave
Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。可以通过lastsave命令获取最后一次成功执行快照的时间。
(3) 执行flushall命令,也会产生dump.rdb文件,但是里面时空的,无意义。
将备份文件(dump.rdb)移动到redis安装目录并启动服务即可。
Config get dir获取目录。
(1)适合大规模的数据恢复。
(2)对数据完整性和一致性要求不高。
(1)在一定间隔时间做一次备份,所以如果redis以为down掉的话,就会丢失最后一次快照后的所有修改。
(2)fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑。
动态所有停止RDB保存规则的方法:redis-cli config set save " "。
以日志的形式来记录每个操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许最近文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就会根据日志文件的内容将写入指令从前到后执行一次以完成数据的恢复工作。
1)正常恢复
A、启动
设置为Yes,修改appendonly no为yes
B、保存
将所有的aof文件复制一份保存到对应目录(config get dir)
C、恢复
重启redis然后重新加载
2)异常恢复
A、启动
设置为Yes,修改appendonly no为yes
B、备份被写坏的AOF文件
C、修复
Redis-check-aof –fix进行修复
D、恢复
重启redis然后重新加载
1)是什么
AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof。
2)重写原理
AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
3)触发机制
Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。
(1)每修改同步
appendfsync always 同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好
(2)每秒同步
appendfsync everysec 异步操作,每秒记录 如果一秒内宕机,有数据丢失
(3)不同步
appendfsync no 从不同步
(1)相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb。
(2)aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同。
可以一次执行多个命令,本质一组命令的集合,一个事务中的所有命令都会序列化,按顺序地串行执行而不会被其他命令插入,不许加塞。
一个队列中,一次性、顺序性、排他性地执行一系列命令。
(1)取消事务
格式:
redis 本地IP:端口号 DISCARD
(2)执行所有事务块内地命令
Exec
(3)取消watch事务块内的命令
Unwatch
(4) 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
Wach key[key……]
(5) watch监控
1)乐观锁/悲观锁/CAS
(1)悲观锁
悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
(2) 乐观锁
乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。
乐观锁策略:提交版本必须大于记录当前版本才能执行更新。
2)有加塞篡改
监控了key,如果key被修改了,后面一个事务的执行失效。
3)小结
(1)Watch指令,类似乐观锁,事务提交时,如果Key的值已被别的客户端改变,比如某个list已被别的客户端push/pop过了,整个事务队列都不会被执行。
(2)通过WATCH命令在事务执行之前监控了多个Keys,倘若在WATCH之后有任何Key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回Nullmulti-bulk应答以通知调用者事务执行失败。
(1)开启
以MULTI开始一个事务。
(2)入队
将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面。
(3)执行
由EXEC命令触发事务。
(1)单独地隔离操作
事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
(2)没有隔离级别的概念
队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题。
(3)不保证原子性
redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。
进程间的一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
先订阅后发布后才能收到消息,
1 可以一次性订阅多个,SUBSCRIBE c1 c2 c3。
2 消息发布,PUBLISH c2 hello-redis。
3 订阅多个,通配符*, PSUBSCRIBE new*。
4 收取消息, PUBLISH new1 redis2015。
行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主。
(1)读写分离
(2)容灾恢复
(1)配从(库)不配主(库)
(2)从库配置
每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件。
info replication
(3)修改配置文件细节操作
1)拷贝redis.conf文件
2)开启daemonize yes
3)pid文件名字
4)指定端口
5)log文件名字
6)dump.rdb名字
(4)常用3招
1)一仆二主
A.Init
B.一个Master两个Slave
C.日志查看
(1)主机日志
(2)备机日志
(3)info replication
D.主从问题
2)薪火相传
A.上一个Slave可以是下一个slave的Master,Slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻master的写压力。
B.中途变更转向
会清除之前的数据,重新建立拷贝最新的。
C.slaveof 新主库IP 新主库端口
3)反客为主
SLAVEOF no one:使当前数据库停止与其他数据库的同步,转成主数据库
(1) slave启动成功连接到master后会发送一个sync命令。
(2) Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步。
(3)全量复制
而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
(4)增量复制
Master继续将新的所有收集到地修改命令一次传给clave,完成同步。
(5)但是只要是重新连接master,一次完全同步(全量复制)将被自动执行。
(1)是什么
反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。
(2)怎么玩(使用步骤)
(1)调整结构,6379带着80、81
(2)自定义的/myredis目录下新建sentinel.conf文件,名字绝不能错
(3)配置哨兵,填写内容
(1)sentinel monitor被疾控数据库名字(自己起名字)127.0.0.1:6379 1
(2)上面最后一个数字1,表示主机挂掉后salve投票看让谁集体成为主机,得票数多少后成为主机
(4)启动哨兵
(1)redis-sentinel/myredis/sentinel.conf
(2)上述目录依照各自地实际情况配置,可能目录
(5)正常主从演示
(6)原有的master挂了
(7)投票新选
(8)重新主从继续开工,info replication查查看
(9)问题:如果之前的master重启回来,会不会双master冲突?
(3)一组sentinel能同时监控多个Master