为什么要用redis?redis为什么这么快?

1.什么是redis

        redis,即远程字典服务,是一个高性能的key-value数据库,也是非关系型数据库

         redis是一个开源(BSD许可)的,内存中的数据结构存储系统,他可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication)LUA脚本(Lua scripting), LRU驱动事件(LRU eviction)事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

2.redis都可以干什么

  • 计算器:利用redis中原子性的自增操作,我们可以统计类似用户点赞数、用户访问数等,这类操作如果使用MySQL,频繁的读写会带来相当大的压力。
  • 限速器:限速器比较典型的使用场景是限制某个用户访问某个api的频率,常用的有,抢购时,防止用户疯狂点击带来的不必要的压力
  • 好友关系:利用set集合的一些命令,比如求交集、并集、差集等。可以方便搞定一些共同好友、共同爱好之类的功能
  • 简单消息队列:除了redis自身的发布/订阅模式,我们也可以利用list来实现一个队列机制。比如,到货通知、邮件发送之类的需求,不需要高可靠,但是会带来非常大的DB压力,完全可以用list来完成一部解耦。
  • session共享:以PHP为例,默认session是保存在服务器的文件中,如果是集群服务,同一个用户过来可能落在不同机器上,这就会导致用户频繁登录;采用redis保存session后,无论用户落在那台机器上都能获取到对应的session信息。

3.redis的特点及优势 

特点:

  • redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加在进行使用。
  • redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的储存
  • redis支持数据的备份,即master-slave模式的数据备份

优势:

  • 性能极高——redis能读得的速度是110000次/s,写的速度是81000次/s。
  • 丰富的数据类型——redis支持二进制案例的Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子——redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过multi和exec指令包起来。
  • 丰富的特性-redis还支持publish/subscribe,通知,key过期等等特性

4.redis为什么这么块

  1. 基于内存:(拿MySQL与redis做下对比)

 

 MySQL是持久化存储的,数据存放在磁盘里面,检索的话,会涉及到一定的IO,为了解决这个瓶颈,于是出现了缓存,加快检索速度

(ps  IO瓶颈:

关于IO的几个指标解释:

  • bi:读磁盘的速度,单位KB/秒
  • bo:写磁盘的速度
  • wa:IO的时间

瓶颈分析:

1:wa并不能反应磁盘的瓶颈,实际反应的是cpu的io等待时间

2:bi+bo 参考值为1000,如果超过1000,而且wa值比较大,标示系统磁盘IO存在瓶颈 

        内存和硬盘的关系,硬盘放置主体数据用于持久化存储,而内存则是当前运行的那部分数据,CPU访问内存而不是磁盘,这大大提升了运行的速度,当然这是基于程序的局部化访问原理。

         推理到redis+MySQL,他是内存+磁盘关系的一个映射,MySQL放在磁盘,redis放在内存,这样的话,web应用每次只访问redis,如果没有找到数据,才回去访问MySQL

 2.  单线程: 

多线程的问题:

  • 锁机制造成性能降低

               Java中与hash相关的集合有HashMap,HashTable,ConcurrentHashMap等,其中HashMap是线程不安全的,就是如果多线程环境中有多个线程同时操作该集合的话,可能导致数据污染的问题,因而有了HashTable的出现。但是在实际操作中,发现HashTable的性能比较低,因为HashTable靠一把锁来维护全部的数据,所有的线程在操作数据时只能去竞争那一把锁,造成线程等待,故而新能降低。为了克服这个问题,在JDK1.5~1.7版本,Java使用了分锁机制实现ConcurrenHashMap。这就是多线程中锁机制造成的性能降低。

  • 上下文切换造成时间消耗

                CPU的每个核在一个时刻只能运行一个线程,当在运行一个线程的过程中转去运行另外一个线程,这个叫做线程上下文切换。由于可能当前线程的任务并没有执行完毕,所以在切换时需要保存线程的运行状态,以便下次重新切换回来时能够继续切换之前的状态运行。每一次切换都是需要花时间的,所以在计算密集型的任务中,多线程的数量不宜超过CPU的核心数,吵过之后CPU只是会徒劳的花时间在上下文切换上。

而redis使用单线程,就不需要考虑上述问题了。

 3. IO多路复用

        其实单线程也是存在问题的,由于线程的执行过程是顺序执行的加上读写操作等待用户输入或输出都是阻塞的,所以IO操作一般情况下不能直接返回,这会导致某个文件的IO阻塞,导致整个进程无法对其他客户提供服务。为了解决这个问题,因此有了IO多路复用

        IO多路复用的核心是用户进程调用select函数被阻塞,同时内核轮询监听所有select负责的socket,当任何一个socket有数据准备好了,select就将控制权返回给用户进程。

        多路复用的具体实现方式有select/poll/epoll等,redis内部实现采用了epoll+自己实现的简单的事件框架。

        相比select和poll,epoll有以下几个优势:

  • epoll没有最大连接数限制(select的最大限制为1024)
  • epoll最大的有点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,epoll的效率就远远高于select和poll
  • 内存拷贝,select和poll在数据准备好之后,需要把数据从内核拷贝到用户进程,epoll使用了“共享内存”,避免了内存拷贝。
  • epoll线程安全

总结:redis使用了IO多路复用,保证了redis在进行IO操作是依然能处理socket请求,不会再IO上浪费时间;单线程机制也避免了不必要的上下文切换和锁机制;而redis的每一次IO操作都是基于内存的,非常高效。可以说,redis的这三个特性相辅相成,共同造就了redis的高并发。

5.kafka与redis区别

举一个例子,来说:

老师有个好消息要告诉同学们,有两种方式。

1.去到每个人的座位上,挨个说。(此时,小明不在座位上,就只能错过这个好消息了)

2.老师把好消息写到黑板上,三天后就会擦掉,谁想知道谁来看。(此时,小明请假一周,他就会错过这个好消息)

redis用第一种办法,kafka用第二种办法

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值