Redis是一个key-value的nosql数据库.先存到内存中,会根据必定的策略持久化到磁盘,即便断电也不会丢失数据。支持的数据类型比较多。java
主要用来作缓存数据库的数据和web集群时当作中央缓存存放seesion。mysql
守护进程:在linux或者unix操做系统中在系统引导的时候会开启不少服务,这些服务就叫作守护进程。为了增长灵活性,root能够选择系统开启的模式,这些模式叫作运行级别,每一种运行级别以必定的方式配置系统。 守护进程是脱离于终端而且在后台运行的进程。守护进程脱离于终端是为了不进程在执行过程当中的信息在任何终端上显示而且进程也不会被任何终端所产生的终端信息所打断。linux
高性能,高可用性和可伸缩性程序员
Redis和Memcache区别:web
Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其余东西,例如图片、视频等等。面试
Redis不只仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。redis
nosql数据库分类:spring
缓存:sql
把常常须要查询的、不多修改数据,放到读速度很快的空间(内存),以便下次访问减小时间。减轻压力,减小访问时间。数据库
计数器:
Redis中的计数器是原子性的内存操做。
session缓存服务器:
web集群时做为session缓存服务器
Json字符串:
须要把对象转换为json字符串,当作字符串处理。直接使用set get来设置或者或。
优势:设置和获取比较简单
缺点:没有提供专门的方法,须要把把对象转换为json。(jsonlib)
字节:须要作序列号,就是把对象序列化为字节保存。
若是是担忧JSON转对象会消耗资源的状况,这个问题须要考量几个地方:
第一点:就是使用的JSON转换lib是否就会存在性能问题。
第二点:就是数据的数据量级别,若是是存储百万级的大数据对象,建议采用存储序列化对象方式。若是是少许的数据级对象,或者是数据对象字段很少,仍是建议采用JSON转换成String方式。
毕竟redis对存储字符类型这部分优化的很是好。具体采用的方式与方法,还要看你所使用的场景。
在 Redis 中,容许用户设置最大使用内存大小 server.maxmemory,在内存限定的状况下是颇有用的。譬如,在一台 8G 机子上部署了 4 个 Redis 服务点,每个服务点分配 1.5G 的内存大小,减小内存紧张的状况,由此获取更为稳健的服务。
内存大小有限,须要保存有效的数据?
Redis 内存数据集大小上升到必定大小的时候,就会施行数据淘汰策略。
Redis 提供 6种数据淘汰策略:
volatile-lru:从已设置过时时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过时时间的数据集(server.db[i].expires)中挑选将要过时的数据淘汰
volatile-random:从已设置过时时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据
使用jedis java客户端来访问redis服务器,有点相似经过jdbc访问mysql同样。
1.String
要把一个String保存到redis中,用set(key,value),获取值用get(key)。
2.Hash(通常用于保存对象)
要把一个Hash保存到redis中,遍历Map<String,String>,逐个调用hset(key,hashKey,hashValue),获取全部值有hgetAll(key)。
3.List
要把一个List保存到redis中,遍历List<String>,逐个调用lpush(key,value),获取值用lrange(key,start,end),start表明开始位置,end表明结束位置,若是为-1则表明到未尾。
这里lpush的意思是从左边保存,也就是后来居上。
4.Set
要把一个Set保存到redis中,遍历Set<String>,逐个调用sadd(key,value),获取值用smembers(key)。
5.SortedSet
SortedSet的意思是他的每个元素是有顺序的,顺序根据其score来决定,若是socre同样,则按value排序。保存到redis的方法是,对每个要保存的元素,调用zadd(key,score,value),获取值用zrange(key,satrt,end),start表明开始位置,end表明结束位置,若是为-1则表明到未尾。
相似mysql的master-slave模式同样,redis的master-slave能够提高系统的可用性,master节点写入cache后,会自动同步到slave上。Master以写为主,Slave以读为主。
能够实现:读写分离和容灾恢复
缺点:延时,因为全部的写操做都是在Master上操做,而后同步更新到Slave上,因此从Master同步到Slave机器有必定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增长也会使得这个问题更加严重。
配置过程:
主Redis:192.168.10.1 6379 从Redis:192.168.10.2 6380
将主从redis配置文件redis.conf中的aemonize no 改成 yes
修改从redis配置文件redis.conf中的port 6379 改成 6380,添加slaveof 192.168.10.1 6379
主Redis:
[root@localhost redis-2.8.3]# src/redis-server /soft/redis-2.8.3-master/redis-2.8.3/redis.conf
从Redis:
[root@localhost redis-2.8.3]# src/redis-server /soft/redis-2.8.3-slave/redis-2.8.3/redis.conf
测试数据同步
主Redis:
[root@localhost redis-2.8.3]# src/redis-cli -p 6379 127.0.0.1:6379> set name abc OK 127.0.0.1:6379> get name "abc" 127.0.0.1:6379>
从Redis:
[root@localhost redis-2.8.3]# src/redis-cli -p 6380 127.0.0.1:6380> get name "abc" 127.0.0.1:6380>
默认是读写分离的
在从Redis:
[root@localhost redis-2.8.3]# src/redis-cli -p 6380 127.0.0.1:6380> set name 123 (error) READONLY You can't write against a read only slave.
[root@localhost redis-2.8.3]# src/redis-cli -n 6379 shutdown [root@localhost redis-2.8.3]# src/redis-cli -p 6379 Could not connect to Redis at 127.0.0.1:6379: Connection refused not connected>
[root@localhost redis-2.8.3]# src/redis-cli -p 6380 slaveof NO ONE OK
[root@localhost redis-2.8.3]# src/redis-cli -p 6380 127.0.0.1:6380> set name 123 OK 127.0.0.1:6380> get name "123" 127.0.0.1:6380>
1)将如今的主redis的数据进行保存
[root@localhost redis-2.8.3]# src/redis-cli -p 6380 127.0.0.1:6380> get name "abc" 127.0.0.1:6380> set name 123 OK 127.0.0.1:6380> get name "123" 127.0.0.1:6380> save OK 127.0.0.1:6380> get name "123" 127.0.0.1:6380>
2)将如今的主redis根目录下dump.rdb文件拷贝覆盖到原来主redis的根目录
3)启动原来的主redis
[root@localhost redis-2.8.3]# src/redis-server /soft/redis-2.8.3-master/redis-2.8.3/redis.conf
4)在如今的主redis中切换
[root@localhost redis-2.8.3]# src/redis-cli -p 6380 slaveof 192.168.10.1 6379 OK
经常使用的设计方案:
一主二仆:一个Master,两个Slave,Slave只能读不能写;当Slave与Master断开后须要从新slave of链接才可创建以前的主从关系;Master挂掉后,Master关系依然存在,Master重启便可恢复。
薪火相传:上一个Slave能够是下一个Slave的Master,Slave一样能够接收其余slaves的链接和同步请求,那么该slave做为了 链条中下一个slave的Master,如此能够有效减轻Master的写压力。若是slave中途变动转向,会清除以前的数据,从新创建最新的。
反客为主: 当Master挂掉后,Slave可键入命令 slaveof no one使当前Redis中止与其余Master redis数据同步,转成Master redis。
复制原理:
Slave启动成功链接到master后会发送一个sync命令;
Master接到命令启动后的存盘进程,同时收集全部接收到的用于修改数据集命令,在后台进程执行完毕以后,master将传送整个数据文件到slave,以完成一次彻底同步;
全量复制:而slave服务在数据库文件数据后,将其存盘并加载到内存中;
增量复制:Master继续将新的全部收集到的修改命令依次传给slave,完成同步;
哨兵模式:
反客为主的自动版,可以后台监控Master库是否故障,若是故障了根据投票数自动将slave库转换为主库。一组sentinel能同时监控多个Master。
使用步骤:
一、在Master对应redis.conf同目录下新建sentinel.conf文件,名字绝对不能错;
sentinel monitor 被监控数据库名字(本身起名字) ip port 1
说明:上面最后一个数字1,表示主机挂掉后slave投票看让谁接替成为主机,得票数多少后成为主机。
三、启动哨兵模式:
命令键入:redis-sentinel /myredis/sentinel.conf
注:上述sentinel.conf路径按各自实际状况配置
普通的链接使用没有办法把Java对象直接存入Redis,而须要咱们本身提供方案-对象序列化,而后存入redis,取回序列化内容后,转换为java对象。Spring模板中提供了封装的方案,在它内部提供了RedisSerializer接口(org.springframework.data.redis.serializer.RedisSerializer)和一些实现类。也能够自定义序列化器,实现RedisSerializer接口。经常使用的有:StringRedisSerializer,JdkSerializationRedisSerializer<T>,GenericToStringSerializer…
RedisTemplate默认的系列化类是JdkSerializationRedisSerializer,用JdkSerializationRedisSerializer序列化的话,被序列化的对象必须实现Serializable接口。在存储内容时,除了属性的内容外还存了其它内容在里面,总长度长,且不容易阅读。 咱们要求是存储的数据能够方便查看,也方便反系列化,方便读取数据。
Jackson2JsonRedisSerializer和GenericJackson2JsonRedisSerializer,二者都能序列化成json,可是后者会在json中加入@class属性,类的全路径包名,方便反系列化。前者若是存放了List则在反系列化的时候若是没指定TypeReference则会报错:java.util.LinkedHashMap cannot be cast to。
WebSocket 是 HTML5 开始提供的一种在单个 TCP 链接上进行全双工通信的协议。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,容许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只须要完成一次握手,二者之间就直接能够建立持久性的链接,并进行双向数据传输。
在 WebSocket API 中,浏览器和服务器只须要作一个握手的动做,而后,浏览器和服务器之间就造成了一条快速通道。二者之间就直接能够数据互相传送。
如今,不少网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,而后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器须要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费不少的带宽等资源。
WebSocket 协议本质上是一个基于 TCP 的协议。
为了创建一个 WebSocket 链接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和一般的 HTTP 请求不一样,包含了一些附加头信息,其中附加头信息"Upgrade: WebSocket"代表这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息而后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 链接就创建起来了,双方就能够经过这个链接通道自由的传递信息,而且这个链接会持续存在直到客户端或者服务器端的某一方主动的关闭链接。
websocket事件触发机制:
open:
一旦服务器响应了WebSocket链接请求,open事件触发并创建一个链接。open事件对应的回调函数称做onopen。
到open事件触发时,协议握手已经完成,WebSocket已经准备好发送和接收数据。若是应用程序接收到一个open事件,那么 能够肯定WebSocket服务器成功地处理了链接请求,而且赞成与应用程序通讯。
message:
WebSocket消息包含来自服务器的数据。你也可能据说过组成WebSocket消息的WebSocket帧(Frame)。第3章将详细讨论消息和帧的概念。为了理解消息使用API的方式,WebSocket API只输出完整的消息,而不是WebSocket帧。message事件在接收到消息时触发,对应于该事件的回调函数是onmessage。
除了文本,WebSocket消息还能够处理二进制数据,这种数据做为Blob消息或者ArrayBuffer消息处理。由于设置WebSocket消息二进制数据类型的应用程序会影响二进制消息,因此必须在读取数据以前决定用于客户端二进制输入数据的类型。
error:
error事件在响应意外故障的时候触发。与该事件对应的回调函数为onerror。错误还会致使WebSocket链接关闭。若是你接收一个error事件,能够预期很快就会触发close事件。close事件中的代码和缘由有时候能告诉你错误的根源。error事件处理程序是调用服务器重连逻辑以及处理来自WebSocket对象的异常的最佳场所。
close:
close事件在WebSocket链接关闭时触发。对应于close事件的回调函数是onclose。一旦链接关闭,客户端和服务器再也不能接收或者发送消息。
说明:WebSocket规范还定义了ping和pong帧,能够用于持续链接(keep-alive)、心跳、网络状态检测、延迟测量等,可是WebSocket API目前没有输出这些特性。尽管浏览器接受ping帧,可是不会触发对应WebSocket上的ping事件。相反,浏览器将自动响应pong帧。然而,浏览器实例化的ping若是在一段时间内没有获得pong应答,可能会触发链接的close事件。
当调用close()方法终止与服务器的链接时,也会触发onclose事件处理程序;WebSocket close事件在链接关闭时触发,这可能有多种缘由,好比链接失败或者成功的WebSocket关闭握手。WebSocket对象特性readyState反映了链接的状态(2为正在关闭,3为已关闭)。
close事件有3个有用的属性(property),能够用于错误处理和恢复:wasClean、code和error。wasClean属性是一个布尔属性,表示链接是否顺利关闭。若是WebSocket的关闭是对来自服务器的一个close帧的响应,则该属性为true。若是链接是由于其余缘由(例如,由于底层TCP链接关闭)关闭,则该属性为false。code和reason属性表示服务器发送的关闭握手状态。这些属性和WebSocket.close()方法中的code和reason参数一致。
针对于上面所涉及到的知识点我总结出了有1到5年开发经验的程序员在面试中涉及到的绝大部分架构面试题及答案作成了文档和架构视频资料免费分享给你们(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术资料),但愿能帮助到您面试前的复习且找到一个好的工做,也节省你们在网上搜索资料的时间来学习,也能够关注我一下之后会有更多干货分享。