redis是一款由C语言开发基于内存但可以持久化的key-value数据库,即非关系型数据库,NoSql(not only sql)
1.2.缓存穿透、缓存击穿、缓存雪崩
.缓存流程:
请求-> 缓存
->没有,查询数据库
->没有,返回null
->有,刷新缓存返回
->有,返回
.缓存穿透:缓存和数据库都没有,不断发起请求,造成数据库压力大,解决:限流
.缓存击穿:并发查同一条缓存过期,但数据库有,导致数据库瞬间压力大,解决:延长过期时间、或不过期、或加分布式锁setifabsent
.缓存雪崩:缓存大面积过期,导致数据库压力大,解决:过期时间分散设置,不要密集在同一时间段
1.3redis缓存淘汰策略:最久未使用、最少使用、先进先出
1.4redis和memcached的区别(总结)
、Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等;
、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储;
、虚拟内存--Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘;
、过期策略--memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10;
、分布式--设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从;
、存储数据安全--memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化);
、灾难恢复--memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复;
、Redis支持数据的备份,即master-slave模式的数据备份;
优点:
*数据是存储在内存中,速度非常快,理论上每秒可以达到11万次的读、8万次的写
*支持事务,当然redis的事务只是保证了,执行语句的完整性并不能保证数据的安全
*数据可以持久化到硬盘
*支持字符串、链表、散列表、有序无序集合5种数据结构
缺点:
*不能像关系型数据库那样高效的处理复杂的存储结构
*没有关系型数据库那样的事务机制以保障数据的安全性
*字符串(String)
最为常用,可以保存JSON格式数据
*双向链表(List)等价于LinkedList
由于链表的特性可以用来做任务队列
*散列表(hash)类似于一个POJO
应用场景较少,可以存储对象POJO信息
*无序集合 (Set) 类似于HashSet
用于存储需要频繁取交集、差集的数据场景,示例如下:
此图引用自hello php的博客
*有序集合(ZSet)类似于TreeSet
可以做类似排行榜的场景,下面是RedisTemplate的ZsetAPI的添加方法
Boolean add(K key, V value, double score); //score就是该键值对的排行
*运维命令:
select 1 切换到数据库1
ping 输出pong则连接redis成功
quit / ctrl+c 退出客户端
info 查看redis信息,如包含的键值对、集群、内存、CPU等
dbsize 显示当前库key的数量
flushall 清空所有的key
flushdb 清空当前库的key
shutdown 停止当前redis
*通用命令:
keys * 显示当前库的key
del key 删除当前key以及value
exists key 判断是否存在key,1表示存在
rename key newKey 修改key的名称
expire key 30 设置key的过期时间为30秒
ttl key 获取key的超时剩余时间,-1未设置超时,-2已超时
type key 获取key的值的类型,有序set集合返回zset
*字符串:
get key 获取key
set key value 设置key
del key删除key
*list:
lrange key start end 获取链表从start到end的元素
rpush key value [...] 向链表头添加元素
lpush key value [...] 向链表尾添加元素
lpop key 删除链表左边第一个元素并返回
rpop key 删除链表右边第一个元素并返回
*hash:
hmset key field1 value1 [field2 value2]... 向key下添加多个字段
hdel key field1 [field2]... 删除key下指的的字段
hset key field value 修改key下一个字段
hkeys key 获取key下的所有字段
hmget key field1 [field2]... 获取给key下定字段的值
*set:
sadd key value [...] 添加
srem key value [...] 删除
smembers key 查询所有元素
scard key 查询集合的元素数量
sismember key value 检查该元素是否存在
*zset:
zadd key score value [...] 添加
zrem key value [...] 删除
zcard key 查询集合的元素数量
zrange key min max withscores 查询某个key下的zset元素,从min到max排序显示,并显示score
multi 开启
exec 执行
discard 回滚
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
因此,redis的事务只是保证多个执行语句入队,并不保证每个语句都执行成功。
rdb模式:照快照模式,适用于大内存服务器,优点:保存还原数据快,缺点:照快照会占用系统大量的内存,内存不足的情况下容易导致宕机数据丢失。配置属性:默认就是最优配置
aof模式:适用于内存较小的服务器,优点:占用较少的内存资源,缺点:日志文件越来越大,不易备份,恢复数据慢,且会持续性占用内存。配置属性:appendfsync 默认每秒,everysec
no:表示等操作系统进行数据缓存同步到磁盘(快)
always:表示每次更新操作后手动调用 fsync() 将数据写到磁盘(慢,安全)
everysec:表示每秒同步一次(折中,默认值)
*主从同步指得是,redis中的数据可以从master主服务器同步到多个slave从服务器上,master可以读写,slave只负责读以及同步master过来的数据,从而实现读写分离,当master宕机,slave会进行重新选举新的master上来。
redis集群是一个由多个主从节点构成的分布式主从群,具有复制、高可用、分片特性。
1.安装redis
*下载redis: redis.io/download
*安装gcc yum install gcc
*安装redis
*新建一个redis目录用于存放redis相关
*解压redis-3.2.12.tar.gz文件到redis目录下 命令:tar -zxvf redis-3.2.12.tar.gz
*进入redis-3.2.12目录下编译 命令:make
*在redis目录下建立conf和bin目录 命令:mkdir {conf,bin}
*把redis-3.2.12/redis.conf文件复制一份到 redis/conf目录下 命令:cp redis.conf /redis/conf
*移动redis-3.2.12/src 下面的常用命令到 redis/bin目录下
命令:mv mkreleasehdr.sh redis-benchmark redis-check-aof redis-check-rdb redis-cli redis-server /root/Desktop/install/redis/bin/
*后台启动指定配置文件,修改/bin/redis.conf里面的daemonize的值为yes,启动命令:/redis-server
*验证是否启动成功 命令:netstat -tunpl |grep 6379
*连接redis 命令:conf/redis.cli
*退出客户端 命令:quit 停止服务:/redis-cli shutdown
2.搭建集群,集群都是奇数个方便选举,以下采用三主三从
*在redis目录下创建cluster目录,在里面分别创建6个目录6301 6302 6303 6304 6305 6306
命令:mkdir -pv cluster/{6301,6302,6303,6304,6305,6306}
*把redis.conf配置文件copy一份修改如下内容:
daemonize yes
port 6301
bind 192.168.43.54 (当前主机的ip)
dir 6301 (指定数据持久化目录)
cluster-enabled yes (启动集群模式)
cluster-config-file nodes-6301.conf (当前节点的conf标识,注意与当前节点启动时的conf文件名无关)
cluster-node-timeout 5000 (当前节点超时5000ms被踢出)
#appendonly yes (每次更新操作都记录日志)
*然后分别传到6301 - 6306目录下
3.安装ruby
yum install ruby
yum install rubygems
gem install redis --version 3.2.12(如果安装失败可以去https://rubygems.org/gems/redis/versions/3.2.1 这里下载)
4.启动集群
*首先启动6个redis实例 命令:bin/redis-server cluster/6302/redis.conf
*组件集群,命令:
redis-3.2.12/src/redis-trib.rb create --replicas 1 192.168.43.54:6301 192.168.43.54:6302 192.168.43.54:6303 192.168.43.54:6304 192.168.43.54:6305 192.168.43.54:6306
*上述命令中搭建的是一主一从,1表示集群中master节点和slave节点的个数比例,即master/slave。
*上述命令中6301、6302、6303为master后面6304为6301从节点,6305为6302从节点,6306为6303从节点,依次类推
5.启动集群成功后连接测试
[root@bogon redis]# bin/redis-cli -c -h 192.168.43.54 -p 6301
192.168.43.54:6301> cluster info #查看集群信息
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_sent:1614
cluster_stats_messages_received:1614
192.168.43.54:6301> cluster nodes #查看集群节点
4af9ae68c3dfa3bccae95ae6e7d2b428861a8780 192.168.43.54:6306 slave 6b06c493684f71df0eb6e4fab890b9171355f407 0 1549946325606 6 connected
a2105be2a1939824394367dfeb59a90b9f4efe3b 192.168.43.54:6305 slave 7f32fb3b3ffa8123a9206dc3093977c91493eb64 0 1549946324099 5 connected
6b06c493684f71df0eb6e4fab890b9171355f407 192.168.43.54:6303 master - 0 1549946324602 3 connected 10923-16383
151f397b61437886ff30d286f85bde2d914b6c20 192.168.43.54:6304 slave d725107ee345c67fb88a45b8321d0d98efbb760a 0 1549946324602 4 connected
d725107ee345c67fb88a45b8321d0d98efbb760a 192.168.43.54:6301 myself,master - 0 0 1 connected 0-5460
7f32fb3b3ffa8123a9206dc3093977c91493eb64 192.168.43.54:6302 master - 0 1549946325103 2 connected 5461-10922
*测试集群数据
192.168.43.54:6301> set username Lucy
-> Redirected to slot [14315] located at 192.168.43.54:6303
OK
192.168.43.54:6303> get username
"Lucy"