Nosql: Not only sql ; 非关系型数据库
随着数据访问量的增大,数据库的IO压力不断增大,服务器的cup及内存压力
Redis:
支持的数据类型:(都是以键值对的形式存在的)
string
list :有序可重复
set :无序不可重复
zset(sorted set) 像Java中的sorted Map:有序而不可重复
hash(hash类型)像Java中的map
这些数据类型都支持:push(推)/pop(弹) , add/remove
master-slave:主从复制
配合关系型数据库做高速缓存
高频次,热门访问的数据,降低数据库IO
分布式架构,做sessio共享
有了redis后的访问过程:
客户端访问服务器,服务器会先去缓存中取数据,有的话,则不访问数据库,没有则去访问数据库,先将数据放在缓存中,再给客户端响应
redis安装:
官网下载:https://www.redis.net.cn/tutorial/3503.html
放在opt文件夹下:
tar -zxvf 安装包名
进入redis-5.0.4, cd redis-5.0.4/
执行make命令,会报以下错误,由于redis是c语言开发的,所以需要c语言的环境
能上网:
yum install gcc
yum install gcc-c++
查看版本:
gcc -v
g++ -v
再次执行make还是会报错:
此时需要清除一下
解决方案:
执行命令:make distclean之后再 make
这样就是安装成功了
之后执行make install
这样就安装完成了
默认安装路径:usr/local/bin
进入usr/local/bin
Redis-sentinal:哨兵,redis集群使用
redis-cli:客户端,操作入口
redis-server:redis服务器启动命令
Redis-benchmark:性能测试工具,可以试试,看看自己本子性能如何(服务启动起来后执行)
redis-check-aof:修复有问题的AOF文件
redis-check-rdb:修复有问题的dump.rdb文件
在该目录下的话就可以在任何目录下启动:
redis-server: 启动 ,ctrl+c停止启动
redis的配置文件:redis.conf
先将redis配置文件复制一份,
后台启动:
1.备份redis.conf:拷贝一份redis.conf到其他目录
2.修改redis.conf文件将里面的daemonize no 改成yes ,(这个配置就是让redis在后台启动的)
vim redis.conf后
shift+G:跳到文件最后
/输入要查找的内容 (这里是 )/daemonize 回车就可以查找到指定位置,按n跳到下一个定位
3.启动命令:(在其他目录下)执行
redis-server /opt/myRedis/redis.conf
在opt/myRedis目录下:redis-server redis.conf
查看redis是否启动:
ps -ef | grep redis
ip+端口号:127.0.0.1:6379
启动客户端:
redis-cli
退出客户端:exit 或者ctrl+C
这样代表连接成功
关闭服务端:
shutdown
redis-cli shutdown
redis-cli -p 6379 shutdown
默认有16个数据库,通常使用0号数据库
memcached :
一般不持久化;
只有一种数据类型;
多线程+锁
redis:
持久化
五种数据类型
单线程+多路IO复用
阻塞IO:做一次,一直等待
非阻塞IO:一直做,做多次,
IO多路复用:监视住,自己做其他事情
select:限制1024个,一个一个问
poll:不限制数量,一个一个监视
epoll:不限制数量,为每个标上标识符
五大数据类型:(其实redis中只能存储字符串)
keys * :查看当前数据库中所有的键
exists 键名:存在返回1,否则返回0
type 键名:查看键的类型
del 键名:删除键
expire 键名 时间(以秒为单位) :为键设置过期时间
-1代表永不过期,-2代表已过期
ttl 键名: 查看还有多少秒过期
dbsize:查看当前数据库key的数量
Flushdb:清空当前数据库
Flushall:清空16个数据库,最好不要用,删库跑路
get 键名(key) :查询对应键的value
set key value :添加键值对
append key value:将给定value追加到原值的末尾
strlen key:查看value的长度
setnx key value:只有在key 不存在时,设置key值
incr key:将key中存储的数据的值增加1,只能对数值进行操作
decr key:将key中存储的数据的值减少1,只能对数值进行操作
incrby/decrby key 步长:将key中存储的数据的值增加/减少 步长,只能对数值进行操作
mset key1 value1 key2 value2 key3 value3:设置多个键值对
mget key1 key2 key3:获取多个值
msetnx key1 value1 key2 value2 key3 value3:
同时设置一个或多个key-value对,当且仅当所有的key不存在时才会设置成功
getrange key 起始位置 结束位置:
获取范围内的值,包前也包后,类似于java中的substring
setrange key 起始位置 value:
从起始位置开始覆写key所存储的字符串的值
setex key 过期时间 value
设置键值的同时设置过期时间,单位秒
getset key value:
以新换旧,设置新值同时获取旧值
list:单键多值,双向链表,里面存储的都是字符串,可重复的
lpush/rpush key value1 value2 value3 …
从左边/右边插入一个或多个值
lpop/rpop key
从左边或者右边弹出一个值
值在建在,值光键亡
rpoplpush key1 key2
从key1右边弹出一个值,插到key2的左边
lrange key start stop:按照索引下标获得元素(从左到右)
lindex key index
按照索引下标获取元素(从左到右)
llen key
获取列表长度
linsert key before :
在value的前面插入,如果有重复,则在左边第一个插入
lrem
从左边删除n个value(从左到右)
当n为正数时,从左边开始删除,删除左边的2,右边的还在
n为负数,删除右边的1
n为2,删除两个3
当n为0,删除所有的value值,这里删除所有xyz
set :set是可以自动排重,就是不可重的,set是string类型的无序集合,他底层其实是一个value为null的hash表,所以增删改的时间复杂度都是哦O(1)
sadd …将一个或者多个元素添加到键为key的set集合中,自动排重
smembers :取出该集合的所有值
sismember :判断集合key是否有该value的值,有则返回1,没有则返回0
scard :返回该集合的元素个数
srem … :删除集合中的某个元素
spop :随机从该集合中吐出count个值,实现一个抽奖的功能(会删除突出的值)
srandmember :随机从该集合中取出n个值,不会从集合中删除
sinter :
返回两个集合的交集元素
sunion
返回两个集合的并集元素
sdiff
返回两个集合的差集元素,key1和key2位置对调效果不一样
hash
redis hash 是一个键值对集合
redis hash是一个String类型的field和value的映射表,类似于Java中的Map
偶然间才发现Properties类继承了Hashtable,Properties用来存储String类型的键值对,并且对properties文件进行操作,里面有
load方法用来加载properties文件,读取properties中的属性
store方法用来为properties文件来保存属性
hset
给集合中的 键赋值
hget
从集合取出 value
hmset
批量设置hash值
hexists key
查看哈希表key中,给定域field是否存在
hkeys
列出hash表中所有的field
hvals
列出该hash集合的所有value
hgetall
列出所有的和
hincrby
为hash表key中的域field的值加上增量increment
hsetnx
将哈希表key中的域field的值设置为value,当且仅当field不存在时
redis-cli --raw: 可以解决中文乱码
zset(sorted set)
有序集合zset与普通set非常相似,没有重复元素的字符串集合,不同之处是集合的每一个元素关联一个评分(score),这个评分按照最低到最高分的方式排序集合中的成员,集合中的成员是唯一的,但是评分是可以重复的,分数由低到高决定了元素的顺序,
zadd … :
将一个或者多个member元素以及score加入到zset中
注意事项: 添加不同分数的重复元素时,虽然返回的是0,但是会将原来的分数覆盖掉
相同分数不同元素,可以添加,且正常排序
zrange
返回zset中下标在 之间的元素
zrangebyscore key min max [withscores] [limit offset count]
根据分数范围查询元素
返回有序集合key中,所有score值介于min和max之间(包括等于min或max)的成员,有序集合成员按score值递增(从小到大)次序排列
zrevrangebyscore key max min [withscores] [limit offset count]
同上,改为从大到小排序
zrevrange key :
逆序返回zset中下标在 之间的元素
zincrby :
为元素的score加上增量
zrem
删除该集合下,指定值的元素
zcount
统计该集合,分数区间内的元素个数
zrank
返回值在该集合中的排名,从0开始
zset像一个以元素为键,分数为值得Map,应为分数可以重复,元素不可重复
计量单位:大小写不敏感
include: 可以把共用配置文件提取出来,在include中引入
ip地址的绑定:
默认情况下bind=127.0.0.1只能接收本机的访问请求,如果向其他主机访问,需要注释掉这一行,生产环境下肯定要写引用服务器的地址
如果开启了protected-mode,那么在没有设定bind IP 且没有设密码的情况下,Redis只允许接收本机相应请求,可以将这个改为no
tcp-backlog
可以理解是一个请求到达后到接受进程处理前的队列
back-log队列总和=未完成三次握手队列+已完成三次握手队列
高并发情况下tcp-backlog设置值跟超时时限内的redis吞吐量决定
timeout:
一个空闲客户端维持多少秒会关闭,0为永不关闭
TCP keepalive:
对访问的客户端的一种心跳检测,每个n秒检测一次,官方推荐设为60秒
daemonize : 是否为后台进程
pidfile: pid(进程号)
存放pid文件的位置,每个实例会产生一个不同的pid文件
log level:
四个级别根据使用阶段来选择:
logfile: 日志文件名称
查看虚拟机ipv4地址:
redis事务:
Multi:输入的命令会依次进入到命令队列中,但不会执行
Exec:redis会将之前命令队列中的命令依次执行
discard:取消命令
编译错误,事务无法执行
逻辑错误,事务照常执行
取消事务
在关系型数据库中一般都是使用的悲观锁,在非关系新数据库中一般都是使用的乐观锁
watch key [key…]
在执行mulit之前,先执行watch key [key…]监视key操作,key在事务执行之前被其他命令所改动,那么事务被打断
另外一个线程:
这里的nil相当于null
unwatch:取消监视
redis是将数据存在内存中的,它的读写速度非常的快,而且它是单线程+多路IO复用,所以他处理请求的速度也比较快;
Redis事务–秒杀功能(并发)
使用工具ab
下载:yum install httpd-tools
Redis持久化:
RDB (Redis DataBase):
redis会单独fork一个子进程来进行持久化,会将数据写入到一个临时文件,待持久化过程结束了,在用这个临时文件替换上次持久化好的文件。整个过程主进程不需要进行任何的IO操作,确保了极高的性能,如果要对大规模数据恢复,且对数据恢复的完整性不是非常的敏感,RDB方式要比AOF更加高效,RDB的缺点是最后一次持久化的数据可能丢失。
写时复制技术:不是一边写一边复制,而是在需要写的时候才会进行复制
只有在需要持久化的时候才会占用内存,所以一般情况下不会影响的执行
(持久化)保存策略:
save 秒数 更改数 在多少秒内对数据做了多少次数更改才会把数据持久化到dump.rdb
rdb持久化方式在满足持久化策略和正常关闭会对数据持久化,如果最后一次操作没有满足持久化策略而且没有正常关闭redis,可能会造成数据丢失
rdb:保存的是数据,恢复速度快
rdb的缺点:
1.虽然redis在fork时使用的是写时拷贝技术,但是数据量庞大时候还是比较消耗性能的
2.如果redis意外down掉的话,就会丢失最后一次快照后的所有修改
AOF (Append Of File):保存的是写指令,读操作不记录,redis重启的话就更据日志文件的内容将写指令从前到后执行一次以完成数据得恢复工作,所以恢复速度慢
AOF的同步频率:
1.始终同步,每次redis的写入都会立刻记入日志
2.每秒同步,每秒计入一次日志,如果宕机,本秒数据可能丢失
Rewrite:
当AOF文件的大小超过所设定的阈值时,redis就会启动aof文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof
Redis如何实现重写:
重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件
AOF的优点:
备份机制更稳健,丢失数据概率更低;
可以处理误操作
AOF的缺点:
比起RDB占用更多的磁盘空间
恢复备份速度要慢
每次读写都同步的话有一定性能压力
存在个别bug,造成恢复不能
Redis主从复制:
主服务器主要以写为主,从服务器主要以读为主
用处:
读写分离,性能扩展
容灾快速恢复
配从(服务器)不配主(服务器)
拷贝多个redis.conf文件include
开启daemonize yes
Pid文件名字pidfile
指定端口port
Log文件名字
Dump.rdb名字dbfilename
Appendonly关掉或者换名字
删除文件的命令:rm -rvf 文件名
创建并编辑文件:vim 文件名
替换文件所有相同内容:
:%s/原始内容/想要替换内容
info replication:
打印主从复制信息
slaveof
成为某个实例的从服务器
主服务器:
主服务器能都能写:
从服务器只能不能写:
主服务器在设置值时:
此时从服务器掉线,主服务器接着设置值
从服务器重新连接,并且slaveof 为主服务器的从服务器,依然会复制在掉线后从服务器设置的值
主从复制:
不管任何时候从服务器都会与主服务器数据保持一致
从服务器不可以set(写)
当主机掉线,从机原地待命,等待主机重新上线
主机回来后,从机能够照常复制
从机down掉,依然能够跟上大部队
上面的主从关系是临时的:当所有服务器重启后这种关系就会消失
在redis配置文件中可以配置永久的主从关系
复制原理:
每次从机联通后,都会给主机发送sync指令
主机立刻进行存盘操作,发送RDB文件,给从机
从机收到RDB文件后,进行全盘加载
之后每次主机的写操作,都会立刻发送给从机,从机执行相同的命令
薪火相传(服务器链式)
好处:相较于一主多从,当主服务器down掉了,剩下的服务器建立主从关系相对来说简单一些,只需要将原来主服务器的第一个从服务器slave no one 将从机就行
坏处:当中间服务器down掉,后面的从服务器都没法备份
哨兵模式:
反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数从从服务器中选择一个作为主服务器
配置哨兵:
自定义的/myredis目录下新建sentinel.conf文件
在配置文件中填写内容:
sentinel monitor mymaster 127.0.0.1 6379 1
其中mymaster为监控对象起的服务器名称,1 为 至少有多少哨兵认为主机down掉才会自动配置新的主机,这里配置1意义不大,最好配置为3个左右
故障恢复:
新的主服务器的选择:
1.选择优先级靠前的
(优先级在redis.conf中slave-priority 100)
2.选择偏移量最大的
(偏移量是只获得原主数据最多的)
3.选择runid最小的从服务器
(每个redis实例启动后都会随机生成yige40位的runid)
新服务器诞生,其他的从服务器直接从属于该主服务器,
挑选出主服务器之后,sentinel向原主服务器的从服务器发送slaveof 新服务器 的命令,复制新的master
当之前的从服务器上线,sentinel会向其发送slaveof命令,让其成为新主服务器的从服务器。
Redis集群的搭建:
安装ruby环境:
能上网:
执行yum install ruby
执行yum install rubygems
Redis集群提供了以下好处:
1,实现扩容
2.分摊压力
3.无中心配置,相对简单