Redis详解

Redis详解

    • Redis的出现

      • NoSQL数据库了解

      在过去几年中,NoSQL数据库一度成为高并发、海量数据存储解决方案的代名词,与之相应的产品也如同雨后春笋般出现,然而在众多产品中,能够脱颖而出的却屈指可数,如Redis、MongoDB、BerkeleyDB和CouchDB等。由于每种产品所拥有的特性不同,因此它们的应用场景也存在着一定差异。

    1. BerkeleyDB是一种极为流行的开源嵌入式数据库,在更多情况下可用于存储引擎,比如BerlkeyDB再被Oracle收购之前曾作为MySQL的存储引擎,由此可见,该产品拥有极好的并发伸缩性,支持事物及嵌套事物,海量数据存储等重要特性,在用于存储实时数据方面具有极高的可用价值。

    2. MongDB定义为Oriented-Document数据库服务器,和BerkeleyDB不同的是,该数据库可以像其他关系型数据库服务器那样独立的运行并提供相关的数据服务。MongoDB主要适用于论坛或博客等类型的网站,这些网站具有并发访问量高、多读少些、数据量大、逻辑关系简单、以文档数据作为主要数据源等特点,适合用MongoDB提供数据服务。

    3. Memcahced,数据缓存服务器。在使用方式上,它和Redis最为相似,它们之间最大的区别是,memcached只是提供了数据缓存服务,而没有提供任何形式的数据持久化功能,而Redis则提供了这样的功能。一旦Memcached服务器宕机,之前在内存中缓存的数据也将全部消失。再有就是,Redis提供了更为丰富的数据存储结构

    4. Redis,典型的NoSQL数据库服务器。与BerkeleyDB相比,它可以作为服务程序独立运行于自己的服务器主机。Redis除了Key/Value之外还支持List、Hash、Set和Ordered Set等数据结构,因此它的用途也更广泛。

    • Redis是什么

      Redis是由意大利人Salvatore Sanfilippo开发的一款内存高速缓存数据库。Redis本质上是一种键值数据库,但是它在保持键值数据库简单快捷特点的同时,又吸收了部分关系型数库的优点。从而使它的位置处于关系数据库和键值数据库之间。Redis不仅能保存String类型的数据,还能保持lists类型(有序)和Sets类型(无序)的数据,而且还能完成排序(sort)等高级功能,在实现INCR,SETNX等功能的时候,保证了其操作的原子性,除此之外,还支持主从复制功能。

  • Redis的特点

    1. Redis用c语言编写,以内存作为数据存储介质,所以读写数据的效率极高,以设置和获取一个256字节字符串为例,它的读取速度可高达110000次/s,写速度高达81000次/s。

    2. 存储在Redis中的数据是持久化的,断电或重启后,数据也不会丢失。因为Redis的存储分为内存存储、硬盘存储和log文件三部分。重启后,Redis可以从磁盘重新将数据加载到内存中,保证数据不会丢失

    3. 对不同数据类型的操作都是自动的,很安全

    4. Redis支持主从模式,可以配置集群,这样更利于支撑大型的项目

  • Redis的优势

    1. 丰富的数据类型 。Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

    2. Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。

    3. 丰富的特性。 Redis还支持 publish/subscribe, 通知, key 过期等等特性。

    4. 易用性极高。可以利用Redis快速的搭建平台

    5. Redis在解决了很多通用性问题的同时,也为一些个性化问题提供了相关的解决方案,如索引引擎、统计排名、消息队列服务等。

  • Redis的缺点

    数据库容量受到物理内存的限制,不能用作海量数据的高性能读写。因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。

  • Redis的应用场景

    1. 众多语言都支持Redis,因为Redis交换数据快,所以在服务器中常用来存储一些需要频繁调取的数据,这样可以大大节省系统直接读取磁盘来获得数据的I/O开销,更重要的是可以极大提升速度。

    2. 通常局限点来说,Redis以消息队列的形式存在,作为内嵌的List存在,满足实时的高并发需求,而通常在一个电商类型的数据处理过程中,有关商品,热销,推荐排序的队列,通常放在Redis之中,期间也包括Storm对于Redis列表的读取和更新。对于这种热点数据完全可以存到Redis(内存)中,要用的时候,直接从内存取,将会极大的提高了速度和节约了服务器的开销。

  • Redis的两种持久化方式及原理

    Redis数据可以持久化,而且支持的数据类型很丰富。有字符串,链表,集 合和有序集合。支持在服务器端计算集合的并,交和补集(difference)等,还支持多种排序功能。所以Redis也可以被看成是一个数据结构服务器。

    • 第一种方式 ==> filesnapshotting

      默认redis会以快照的形式将数据持久到硬盘(一个二进制文件,dump.rdb,这个文件名字可以指定),在配置文件中的格式是:save N M表示在N秒之内,redis至少发生M次修改则redis抓快照到磁盘。当然我们也可以手动执行save或者bgsave(异步)做快照。

      工作原理:当redis需要做持久化时,redis会fork一个子进程;子进程将数据写到磁盘上一个临时RDB文件中;当子进程完成写临时文件后,将原来的RDB替换掉

    • 第二种方式 ==> Append-only

      filesnapshotting方法在redis异常死掉时,最近的数据会丢失(丢失数据的多少视你save策略的配置),所以这是它最大的缺点,当业务量很大时,丢失的数据是很多的。Append-only方法可以做到全部数据不丢失,但redis的性能就要差些。AOF就可以做到全程持久化,只需要在配置文件中开启(默认是no),appendonly yes开启AOF之后,redis每执行一个修改数据的命令,都会把它添加到aof文件中,当redis重启时,将会读取AOF文件进行“重放”以恢复到redis关闭前的最后时刻。

      AOF文件刷新的方式,有三种,参考配置参数appendfsync :appendfsync always每提交一个修改 命令都调用fsync刷新到AOF文件,非常非常慢,但也非常安全;appendfsync everysec每秒钟都调用fsync刷新到AOF文件,很快,但可能会丢失一秒以内的数据;appendfsync no依靠OS进行刷新,redis不主动刷新AOF,这样最快,但安全性就差。默认并推荐每秒刷新,这样在速度和安全上都做到了兼顾。

      工作原理:首先redis会fork一个子进程;子进程将最新的AOF写入一个临时文件;父进程增量的把内存中的最新执行的修改写入(这时仍写入旧的AOF,rewrite如果失败也是安全的);当子进程完成rewrite临时文件后,父进程会收到一个信号,并把之前内存中增量的修改写入临时文件末尾;这时redis将旧AOF文件重命名,临时文件重命名,开始向新的AOF中写入。

  • Redis使用单进程单线程效率也很快的原因

    1. Redis采用的是基于内存的单进程单线程模型的KV数据库,由c语言编写

    2. 数据结构简单,对数据操作也很简单

    3. 使用多路 I/O复用模型。多路 I/O 复用模型是利用select、poll、epoll可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有I/O事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗),且Redis在内存中操作数据的速度非常快(内存内的操作不会成为这里的性能瓶颈),主要以上两点造就了Redis具有很高的吞吐量。

  • Redis集群方案

    • 为什么需要集群

      通常,为了提高网站响应速度,总是把热点数据保存在内存中而不是从后端服务器读取。但是在大型网站,热点数据往往数据量巨大,这需要由多台主机协调提供服务,这需要由多台主机协同提供服务,即分布式多个Redis实例协同运行

    • 集群方案

      1. 官方Redis集群方案 Redis Cluster

        Redis Cluster可以说是服务端Sharding分片技术的体现,即将键值按照一定算法合理的分配到各个实例分片上,同时各个实例节点协调沟通,共同对外承担一致服务。Redis Cluster中,Sharding采用slot(槽)的概念,一共分成16384个槽,对于每个进入Redis的键值对,根据key进行散列,分配到这16384个slot的某一个中。使用的hash算法也比较简单,就是CRC16后16384取模。

        Redis集群中的每个node(节点)负责分摊这16384个slot中的一部分,也就是说,每个slot都对应一个node负责处理,当动态添加或者减少node节点时,需要将16384个槽再分配,槽中的键值也要迁移。Redis集群,要保证16834个槽对应的node都正常工作,如果某个node发生故障,那它负责的slots也就失效,这个集群将不能工作

        为了增加集群的可访问性,推荐方案是将node配置成主从结构。即一个master主节点,挂n个slave从节点。这时,如果主节点失效,Redis Cluster会根据选举算法从slave节点中选择一个上升为主节点,整个集群继续对外提供服务。

        Redis Cluster的新节点识别能力,故障判断能力及故障转移能力是通过集群中的每个node都在和其他nodes进行通信,这别称为集群总线。们使用特殊的端口号,即对外服务端口号加10000。nodes之间的通信采用特殊的二进制协议。

        对于客户端来说,整个cluster被看做一个整体,客户端可以连接任意一个node进行操作,就像操作单一Redis实例一样,当客户端操作的key没有分配到该node上时,Redis会返回转向指令,指向正确的node。

      2. Redis Sharding集群

        Redis Sharding可以说是Redis Cluster出来之前,业界普遍使用的多Redis实例集群方法。其主要思想是采用哈希算法将Redis数据的key进行散列,通过hash函数,特定的key会映射到特定的Redis节点上,这样,客户端就知道向哪个Redis节点操作数据。

        Redis Sharding采用客户端Sharding方式,服务端Redis还是一个个相对独立的Redis实例节点,没有做任何变动。同时,我们也不需要增加额外的中间处理组件,这是一种非常轻量、灵活的Redis多实例集群方法。客户端sharding技术其优势在于服务端的Redis实例彼此独立,,相互无关联,每个Redis实例像单服务器一样运行,非常容易线性扩展,系统的灵活性很强。其不足之处在于:①由于sharding处理放到客户端,规模进步扩大时给运维带来挑战。②服务端Redis实例群拓扑结构有变化时,每个客户端都需要更新调整。③连接不能共享,当应用规模增大时,资源浪费制约优化。

      3. 利用Redis代理中间件twemproxy实现大规模的Redis集群

        twemproxy处于客户端和服务器的中间,将客户端发来的请求,进行一定的处理后(如sharding),再转发给后端真正的Redis服务器。也就是说,客户端不直接访问Redis服务器,而是通过twemproxy代理中间件间接访问。

        twemproxy中间件的内部处理是无状态的,它本身可以很轻松地集群,这样可避免单点压力或故障。由于使用了中间件,twemproxy可以通过共享与后端系统的连接,降低客户端直接连接后端服务器的连接数量。同时,它也提供sharding功能,支持后端服务器集群水平扩展。统一运维管理也带来了方便。

相关推荐