1、Redis在你们项目中是怎么用的?
(1)门户系统中的首页内容信息的展示。(商品类目、广告、热门商品等信息)门户系统的首页是用户访问量最大的,而且这些数据一般不会经常修改,因此为了提高用户的体验,我们选择将这些内容放在缓存中; (2)单点登录系统中也用到了redis。因为我们是分布式系统,存在session之间的共享问题,因此在做单点登录的时候,我们利用redis来模拟了session的共享,来存储用户的信息,实现不同系统的session共享; (3)我们项目中同时也将购物车的信息设计存储在redis中,购物车在数据库中没有对应的表,用户登录之后将商品添加到购物车后存储到redis中,key是用户id,value是购物车对象; (4)因为针对评论这块,我们需要一个商品对应多个用户评论,并且按照时间顺序显示评论,为了提高查询效率,因此我们选择了redis的list类型将商品评论放在缓存中; (5)在统计模块中,我们有个功能是做商品销售的排行榜,因此选择redis的zset结构来实现; 还有一些其他的应用场景,主要就是用来作为缓存使用。
2、对redis的持久化了解不?
Redis是内存型数据库,同时它也可以持久化到硬盘中,redis的持久化方式有两种: (1)RDB(半持久化方式): 按照配置不定期的通过异步的方式、快照的形式直接把内存中的数据持久化到磁盘的一个dump.rdb文件(二进制文件)中; 这种方式是redis默认的持久化方式,它在配置文件(redis.conf)中的格式是:save N M,表示的是在N秒之内发生M次修改,则redis抓快照到磁盘中。
原理:当redis需要持久化的时候,redis会fork一个子进程,这个子进程会将数据写到一个临时文件中;当子进程完成写临时文件后,会将原来的.rdb文件替换掉,这样的好处是写时拷贝技术(copy-on-write),可以参考下面的流程图;
优点:只包含一个文件,对于文件备份、灾难恢复而言,比较实用。因为我们可以轻松的将一个单独的文件转移到其他存储媒介上;性能最大化,因为对于这种半持久化方式,使用的是写时拷贝技术,可以极大的避免服务进程执行IO操作;想对于AOF来说,如果数据集很大,RDB的启动效率就会很高。
缺点:如果想保证数据的高可用(最大限度的包装数据丢失),那么RDB这种半持久化方式不是一个很好的选择,因为系统一旦在持久化策略之前出现宕机现象,此前没有来得及持久化的数据将会产生丢失;rdb是通过fork进程来协助完成持久化的,因此当数据集较大的时候,我们就需要等待服务器停止几百毫秒甚至一秒。
(2)AOF(全持久化的方式) 把每一次数据变化都通过write()函数将你所执行的命令追加到一个appendonly.aof文件里面; Redis默认是不支持这种全持久化方式的,需要将no改成yes
实现文件刷新的三种方式:
no:不会自动同步到磁盘上,需要依靠OS(操作系统)进行刷新,效率快,但是安全性就比较差; always:每提交一个命令都调用fsync刷新到aof文件,非常慢,但是安全; everysec:每秒钟都调用fsync刷新到aof文件中,很快,但是可能丢失一秒内的数据,推荐使用,兼顾了速度和安全。
原理:redis需要持久化的时候,fork出一个子进程,子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令;父进程会继续处理客户端的请求,除了把写命令写到原来的aof中,同时把收到的写命令缓存起来,这样包装如果子进程重写失败的话不会出问题;当子进程把快照内容以命令方式写入临时文件中后,子进程会发送信号给父进程,父进程会把缓存的写命令写入到临时文件中;接下来父进程可以使用临时的aof文件替换原来的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。下面的图为最简单的方式,其实也是利用写时复制原则。 优点: 数据安全性高; 该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机问题,也不会破坏日志文件中已经存在的内容; 如果日志文件过大,可以采用rewriter机制。
缺点: 对于数量相同的数据集来说,aof文件通常要比rdb文件大,因此rdb在恢复大数据集时的速度大于AOF; 根据同步策略的不同,AOF在运行效率上往往慢于RDB,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效; 针对以上两种不同的持久化方式,如果缓存数据安全性要求比较高的话,用aof这种持久化方式(比如项目二中的购物车);如果对于大数据集要求效率高的话,就可以使用默认的。而且这两种持久化方式可以同时使用。
3、做过redis的集群吗?你们做集群的时候搭建了几台,都是怎么搭建的?
针对这类问题,我们首先考虑的是为什么要搭建集群?(这个需要针对我们的项目来说)
Redis的数据是存放在内存中的,这就意味着redis不适合存储大数据,大数据存储一般公司常用hadoop中的Hbase或者MogoDB。因此redis主要用来处理高并发的,用我们的项目二来说,电商项目如果并发大的话,一台单独的redis是不能足够支持我们的并发,这就需要我们扩展多台设备协同合作,即用到集群。
Redis搭建集群的方式有多种,例如:客户端分片、Twemproxy、Codis等,但是redis3.0之后就支持redis-cluster集群,这种方式采用的是无中心结构,每个节点保存数据和整个集群的状态,每个节点都和其他所有节点连接。我们项目中也使用的是redis-cluster集群。
集群这块直接说是公司运维搭建的,小公司的话也有可能由我们自己搭建,开发环境我们也可以直接用单机版的。但是学员可以了解一下redis的集群版。搭建redis集群的时候,对于用到多少台服务器,每家公司都不一样,大家针对自己项目的大小去衡量。举个简单的例子: 我们项目中redis集群主要搭建了6台,3主(为了保证redis的投票机制)3从(高可用),每个主服务器都有一个从服务器,作为备份机。
4、Throw和throws的区别。
位置不同 1. throws 用在函数上,后面跟的是异常类,可以跟多个;而 throw 用在函数内,后面跟的 是异常对象。
功能不同: 1. throws 用来声明异常,让调用者只知道该功能可能出现的问题,可以给出预先的处理方 式;throw抛出具体的问题对象,执行到throw,功能就已经结束了,跳转到调用者,并 将具体的问题对象抛给调用者。也就是说 throw 语句独立存在时,下面不要定义其他语 句,因为执行不到。
2. throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw 则是抛出了异常, 执行throw则一定抛出了某种异常对象。 3.两者都是消极处理异常的方式,只是抛出或者可能抛出异常,但是不会由函数去处理异 常,真正的处理异常由函数的上层调用处理。
5、服务熔断机制可以讲一下吗?
在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个 系统不可用的情况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因“服务提供者”的不 可用导致“服务消费者”的不可用,并将不可用逐渐放大的过程。
熔断器的原理很简单,如同电力过载保护器。它可以实现快速失败,如果它在一段时间内侦测到 许多类似的错误,会强迫其以后的多个调用快速失败,不再访问远程服务器,从而防止应用程序 不断地尝试执行可能会失败的操作,使得应用程序继续执行而不用等待修正错误,或者浪费 CPU 时间去等到长时间的超时产生。熔断器也可以使应用程序能够诊断错误是否已经修正,如果已经 修正,应用程序会再次尝试调用操作。
Hystrix 断路器机制
断路器很好理解, 当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会 切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务. 断路器保持在开路状态 一段时间后(默认 5 秒), 自动切换到半开路状态(HALF-OPEN). 这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN). Hystrix的断路器 就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效 请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。