Redis的简单认识和面试小问题

Redis:(REmote DIctionary Server)用C语言编写完全开源免费的

是一个高性能的(key/value)分布式内存数据库,基于内存运行

支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,

也被人们称为数据结构服务器

 

单进程模型来处理客户端的请求。对读写等事件的响应是通过对epoll来做的,epollLinux内核为处理大批量文件描述符而作了改进的poll,

为什么用

redis源码可以看出,redisio模型主要是基于epoll实现的,不过它也提供了 selectkqueue的实现,默认采用epoll

Redis是将数据存放在内存中,大大提高了并发性.在高并发情况下如果每次请求都去数据库中查询就会导致数据库宕机,严重浪费资源,存放在内存中,不需要重复的进行io操作,存取速度也大大的得到提升.我们以前就是就是根据他的这个特性将商品的信息放到redis的内存中,并给它设置过期时间,尤其针对一些访问比较频繁的商品,在在用户查询时加入内存并设置过期时间,下次再有用户访问就直接在内存中提取数据.当时这样应用大大提升了性能,在并发量大的情况下性能得到了很好的提升.

而且redis相对其他内存数据库外还支持持久化,能够将内存中的数据进行持久化到磁盘中,在对一些重要的数据进行操作的时候可以实时存储.redis持久化方式两种rdbaof,默认使用的是rdb.rdb在指定的时间间隔内将内存中的数据进行快照写入磁盘.它适用于大规模的数据恢复,且对数据不是很敏感.aof以日志的形式记录每个写操作,将redis的所有的指令以追加的形式记录,我们以前就是对商品的促销才放入redis的,当时使用的就是rdb进行的存储.但是使用性能很好,没出什么问题.促销活动也进行的很顺利,老板也很开心.而且redis化支持事物,也支持消息的发布订阅,不过被应用的并他不能对消息的持久化.他也可以进行主从复制,执行读写分离.以前经常用他的哨兵模式进行防止宕机,现在使用的较多的还是redis的集群,我也自己练习着搭过.

 

技术对比

想比memcache而言redis能将数据持久化,在对一些重要数据操作情况下,起了很好的作用,重启后数据不会丢失,相比看来更加靠谱更加严密.他在对传输小数据时性能比memcache快但是如果大于100k他的性能就不及memcache,因为memcache是多核的,redis是单核的.Memcached单个key-value大小有限,一个value最大只支持1MB,而Redis最大支持512MB.可以支持存放一些比较大的数据.

项目的使用

我第一次使用Redis是在一家公司里面,这家公司需要对一个保存了6万个客户联系方式的关系数据库进行搜索,搜索可以根据名字、邮件地址、所在地和电话号码来进行,每次搜索需要花费1015秒的时间。在花了一周时间学习Redis的基础知识之后,我使用Redis重写了一个新的搜索引擎,然后又花费了数周时间来仔细测试这个新系统,使它达到生产级别,最终这个新的搜索系统不仅可以根据名字、邮件地址、所在地和电话号码等信息来过滤和排序客户联系方式,并且每次操作都可以在50毫秒之内完成,这比原来的搜索系统足足快了 200 倍。因为在内存中进行操作数据比你在硬盘中操作数据快很多.

遇到的问题

我们以前在公司使用redis遇到一个问题,当时在电脑上执行fluashAll删除所有的库内容,当时找了很久都没找到.当时使用的是aof进行数据的持久化,aof的日志文件也存在,重启也执行了,日志文件但是还是没数据.最后找了大概半小时,终于在aof中找到了问题.执行的fluashAll记录在日志文件里面,也在开机的时候执行了,进行了删库操作,所以重启后才没数据的.,当把fluashAll去掉就有数据了

key值过长

由于项目里面的redis是单机的,对空间的使用很关注,key值不宜过长。当数据量很大时,key值也是不小的开销。

面试题总结

为什么redis需要把所有数据放到内存中?

Redis为了达到最快的读写速度将所需数据读到内存中,并通过异步的方式将数据写入磁盘。如果不将数据放在内存中,磁盘I/O速度为严重影响程序的性能。在内存越来越便宜的今天,redis将会越来越受欢迎。

哨兵模式

能够后台监控主机是否故障,如果故障根据投票数自动将从库换为主库.

MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据

相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:

voltile-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)中任意选择数据淘汰

 

 

redis优化

修改linux内核内存分配策略

redis在备份数据的时候,会fork出一个子进程,理论上child进程所占用的内存和parent是一样的,比如parent占用的内存为8G,这个时候也要同样分配8G的内存给child,如果内存无法负担,往往会造成redis服务器的down机或者IO负载过高,效率下降。所以内存分配策略应该设置为 1(表示内核允许分配所有的物理内存,而不管当前的内存状态如何)。

内存分配策略有三种可选值:012

0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。

1, 不管需要多少内存,都允许申请。

2, 只允许分配物理内存和交换内存的大小。(交换内存一般是物理内存的一半)

/etc/sysctl.conf添加

[python] view plain copy 

1. vm.overcommit_memory = 1    //然后重启服务器  

或者执行

[python] view plain copy 

1. sysctl vm.overcommit_memory=1   //立即生效  

Epoll

epollLinux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。

优点

1. epoll 没有最大并发连接的限制,上限是最大可以打开文件的数目,这个数字一般远大于 2048, 一般来说这个数目和系统内存关系很大  ,具体数目可以 cat /proc/sys/fs/-max 察看。

2. 效率提升, Epoll 最大的优点就在于它只管你“活跃”的连接 ,而跟连接总数无关,因此在实际的网络环境中, Epoll 的效率就会远远高于 select poll

3. 内存拷贝, Epoll 在这点上使用了“共享内存 ”,这个内存拷贝也省略了。

Rdb的运作方式

RDB快照过程: 
1Redis使用fork函数复制一份当前的父进程作为子进程 
2、父进程继续处理用户的请求,子进程开始把内存中的数据持久化到磁盘上 
3、当子进程把内存中的数据写入到临时文件完成之后,会把该临时文件替换掉旧的RDB文件。

Aof的运作方式

1、Redis 执行 fork() ,现在同时拥有父进程和子进程。 
2、子进程开始将新 AOF 文件的内容写入到临时文件。 
3、对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF 文件的末尾: 这样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。 
4、当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。 

主从复制

redis的复制功能是支持多个数据库之间的数据同步。一类是主数据库(master)一类是从数据库(slave),主数据库可以进行读写操作,当发生写操作的时候自动将数据同步到从数据库,而从数据库一般是只读的,并接收主数据库同步过来的数据,一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。

通过redis的复制功能可以很好的实现数据库的读写分离,提高服务器的负载能力。主数据库主要进行写操作,而从数据库负责读操作。

过程:

1:当一个从数据库启动时,会向主数据库发送sync命令,

2:主数据库接收到sync命令后会开始在后台保存快照(执行rdb操作),并将保存期间接收到的命令缓存起来

3:当快照完成后,redis会将快照文件和所有缓存的命令发送给从数据库。

4:从数据库收到后,会载入快照文件并执行收到的缓存的命令。

哨兵模式

Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。

集群

redis集群是一个无中心的分布式Redis存储架构,可以在多个节点之间进行数据共享,解决了Redis高可用、可扩展等问题。

好处:

1、将数据自动切分(split)到多个节点

2、当集群中的某一个节点故障时,redis还可以继续处理客户端的请求。

 

一个 Redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个数据都属于这16384个哈希槽中的一个。集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽。集群中的每一个节点负责处理一部分哈希槽。

 

集群中的主从复制

集群中的每个节点都有1个至N个复制品,其中一个为主节点,其余的为从节点,如果主节点下线了,集群就会把这个主节点的一个从节点设置为新的主节点,继续工作。这样集群就不会因为一个主节点的下线而无法正常工作。

Redis:(REmote DIctionary Server)用C语言编写完全开源免费的

是一个高性能的(key/value)分布式内存数据库,基于内存运行

支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,

也被人们称为数据结构服务器

 

单进程模型来处理客户端的请求。对读写等事件的响应是通过对epoll来做的,epollLinux内核为处理大批量文件描述符而作了改进的poll,

为什么用

redis源码可以看出,redisio模型主要是基于epoll实现的,不过它也提供了 selectkqueue的实现,默认采用epoll

Redis是将数据存放在内存中,大大提高了并发性.在高并发情况下如果每次请求都去数据库中查询就会导致数据库宕机,严重浪费资源,存放在内存中,不需要重复的进行io操作,存取速度也大大的得到提升.我们以前就是就是根据他的这个特性将商品的信息放到redis的内存中,并给它设置过期时间,尤其针对一些访问比较频繁的商品,在在用户查询时加入内存并设置过期时间,下次再有用户访问就直接在内存中提取数据.当时这样应用大大提升了性能,在并发量大的情况下性能得到了很好的提升.

而且redis相对其他内存数据库外还支持持久化,能够将内存中的数据进行持久化到磁盘中,在对一些重要的数据进行操作的时候可以实时存储.redis持久化方式两种rdbaof,默认使用的是rdb.rdb在指定的时间间隔内将内存中的数据进行快照写入磁盘.它适用于大规模的数据恢复,且对数据不是很敏感.aof以日志的形式记录每个写操作,将redis的所有的指令以追加的形式记录,我们以前就是对商品的促销才放入redis的,当时使用的就是rdb进行的存储.但是使用性能很好,没出什么问题.促销活动也进行的很顺利,老板也很开心.而且redis化支持事物,也支持消息的发布订阅,不过被应用的并他不能对消息的持久化.他也可以进行主从复制,执行读写分离.以前经常用他的哨兵模式进行防止宕机,现在使用的较多的还是redis的集群,我也自己练习着搭过.

 

技术对比

想比memcache而言redis能将数据持久化,在对一些重要数据操作情况下,起了很好的作用,重启后数据不会丢失,相比看来更加靠谱更加严密.他在对传输小数据时性能比memcache快但是如果大于100k他的性能就不及memcache,因为memcache是多核的,redis是单核的.Memcached单个key-value大小有限,一个value最大只支持1MB,而Redis最大支持512MB.可以支持存放一些比较大的数据.

项目的使用

我第一次使用Redis是在一家公司里面,这家公司需要对一个保存了6万个客户联系方式的关系数据库进行搜索,搜索可以根据名字、邮件地址、所在地和电话号码来进行,每次搜索需要花费1015秒的时间。在花了一周时间学习Redis的基础知识之后,我使用Redis重写了一个新的搜索引擎,然后又花费了数周时间来仔细测试这个新系统,使它达到生产级别,最终这个新的搜索系统不仅可以根据名字、邮件地址、所在地和电话号码等信息来过滤和排序客户联系方式,并且每次操作都可以在50毫秒之内完成,这比原来的搜索系统足足快了 200 倍。因为在内存中进行操作数据比你在硬盘中操作数据快很多.

遇到的问题

我们以前在公司使用redis遇到一个问题,当时在电脑上执行fluashAll删除所有的库内容,当时找了很久都没找到.当时使用的是aof进行数据的持久化,aof的日志文件也存在,重启也执行了,日志文件但是还是没数据.最后找了大概半小时,终于在aof中找到了问题.执行的fluashAll记录在日志文件里面,也在开机的时候执行了,进行了删库操作,所以重启后才没数据的.,当把fluashAll去掉就有数据了

key值过长

由于项目里面的redis是单机的,对空间的使用很关注,key值不宜过长。当数据量很大时,key值也是不小的开销。

面试题总结

为什么redis需要把所有数据放到内存中?

Redis为了达到最快的读写速度将所需数据读到内存中,并通过异步的方式将数据写入磁盘。如果不将数据放在内存中,磁盘I/O速度为严重影响程序的性能。在内存越来越便宜的今天,redis将会越来越受欢迎。

哨兵模式

能够后台监控主机是否故障,如果故障根据投票数自动将从库换为主库.

MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据

相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:

voltile-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)中任意选择数据淘汰

 

 

redis优化

修改linux内核内存分配策略

redis在备份数据的时候,会fork出一个子进程,理论上child进程所占用的内存和parent是一样的,比如parent占用的内存为8G,这个时候也要同样分配8G的内存给child,如果内存无法负担,往往会造成redis服务器的down机或者IO负载过高,效率下降。所以内存分配策略应该设置为 1(表示内核允许分配所有的物理内存,而不管当前的内存状态如何)。

内存分配策略有三种可选值:012

0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。

1, 不管需要多少内存,都允许申请。

2, 只允许分配物理内存和交换内存的大小。(交换内存一般是物理内存的一半)

/etc/sysctl.conf添加

[python] view plain copy 

1. vm.overcommit_memory = 1    //然后重启服务器  

或者执行

[python] view plain copy 

1. sysctl vm.overcommit_memory=1   //立即生效  

Epoll

epollLinux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。

优点

1. epoll 没有最大并发连接的限制,上限是最大可以打开文件的数目,这个数字一般远大于 2048, 一般来说这个数目和系统内存关系很大  ,具体数目可以 cat /proc/sys/fs/-max 察看。

2. 效率提升, Epoll 最大的优点就在于它只管你“活跃”的连接 ,而跟连接总数无关,因此在实际的网络环境中, Epoll 的效率就会远远高于 select poll

3. 内存拷贝, Epoll 在这点上使用了“共享内存 ”,这个内存拷贝也省略了。

Rdb的运作方式

RDB快照过程: 
1Redis使用fork函数复制一份当前的父进程作为子进程 
2、父进程继续处理用户的请求,子进程开始把内存中的数据持久化到磁盘上 
3、当子进程把内存中的数据写入到临时文件完成之后,会把该临时文件替换掉旧的RDB文件。

Aof的运作方式

1、Redis 执行 fork() ,现在同时拥有父进程和子进程。 
2、子进程开始将新 AOF 文件的内容写入到临时文件。 
3、对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF 文件的末尾: 这样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。 
4、当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。 

主从复制

redis的复制功能是支持多个数据库之间的数据同步。一类是主数据库(master)一类是从数据库(slave),主数据库可以进行读写操作,当发生写操作的时候自动将数据同步到从数据库,而从数据库一般是只读的,并接收主数据库同步过来的数据,一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。

通过redis的复制功能可以很好的实现数据库的读写分离,提高服务器的负载能力。主数据库主要进行写操作,而从数据库负责读操作。

过程:

1:当一个从数据库启动时,会向主数据库发送sync命令,

2:主数据库接收到sync命令后会开始在后台保存快照(执行rdb操作),并将保存期间接收到的命令缓存起来

3:当快照完成后,redis会将快照文件和所有缓存的命令发送给从数据库。

4:从数据库收到后,会载入快照文件并执行收到的缓存的命令。

哨兵模式

Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。

集群

redis集群是一个无中心的分布式Redis存储架构,可以在多个节点之间进行数据共享,解决了Redis高可用、可扩展等问题。

好处:

1、将数据自动切分(split)到多个节点

2、当集群中的某一个节点故障时,redis还可以继续处理客户端的请求。

 

一个 Redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个数据都属于这16384个哈希槽中的一个。集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽。集群中的每一个节点负责处理一部分哈希槽。

 

集群中的主从复制

集群中的每个节点都有1个至N个复制品,其中一个为主节点,其余的为从节点,如果主节点下线了,集群就会把这个主节点的一个从节点设置为新的主节点,继续工作。这样集群就不会因为一个主节点的下线而无法正常工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值