java面试总结(10)Redis

1.1Redis概述

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模式的数据备份;

2.Redis的优点、缺点

优点:

*数据是存储在内存中,速度非常快,理论上每秒可以达到11万次的读、8万次的写

*支持事务,当然redis的事务只是保证了,执行语句的完整性并不能保证数据的安全

*数据可以持久化到硬盘

*支持字符串、链表、散列表、有序无序集合5种数据结构

缺点:

*不能像关系型数据库那样高效的处理复杂的存储结构

*没有关系型数据库那样的事务机制以保障数据的安全性

3.Redis的5种数据结构,及使用场景

*字符串(String)

最为常用,可以保存JSON格式数据

*双向链表(List)等价于LinkedList

由于链表的特性可以用来做任务队列

*散列表(hash)类似于一个POJO

应用场景较少,可以存储对象POJO信息

*无序集合 (Set)   类似于HashSet

用于存储需要频繁取交集、差集的数据场景,示例如下:

java面试总结(10)Redis_第1张图片

此图引用自hello php的博客

*有序集合(ZSet)类似于TreeSet

可以做类似排行榜的场景,下面是RedisTemplate的ZsetAPI的添加方法

Boolean add(K key, V value, double score); //score就是该键值对的排行

4.Redis常用命令

*运维命令:

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

5.Redis事务

multi 开启

exec 执行

discard 回滚

单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。

事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

因此,redis的事务只是保证多个执行语句入队,并不保证每个语句都执行成功。

6.redis持久化

rdb模式:照快照模式,适用于大内存服务器,优点:保存还原数据快,缺点:照快照会占用系统大量的内存,内存不足的情况下容易导致宕机数据丢失。配置属性:默认就是最优配置

aof模式:适用于内存较小的服务器,优点:占用较少的内存资源,缺点:日志文件越来越大,不易备份,恢复数据慢,且会持续性占用内存。配置属性:appendfsync 默认每秒,everysec

       no:表示等操作系统进行数据缓存同步到磁盘(快)

       always:表示每次更新操作后手动调用 fsync() 将数据写到磁盘(慢,安全)

       everysec:表示每秒同步一次(折中,默认值)

7.redis主从同步读写分离

*主从同步指得是,redis中的数据可以从master主服务器同步到多个slave从服务器上,master可以读写,slave只负责读以及同步master过来的数据,从而实现读写分离,当master宕机,slave会进行重新选举新的master上来。

8.redis高可用集群

redis集群是一个由多个主从节点构成的分布式主从群,具有复制、高可用、分片特性。

9.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"

 

 

你可能感兴趣的:(java,java,redis)