Redis设计思路总结

本文从网络模型、数据结构和内存管理、持久化和多机协作四个角度对redis的设计思路进行分析。
一.网络模型

Redis是典型的基于Reactor的事件驱动模型,单进程单线程,高效的框架总是类似的。网络模型与spp的异步模型几乎一致。

Redis流程上整体分为接受请求处理器、响应处理器和应答处理器三个同步模块,每一个请求都是要经历这三个部分。

Redis集成了libevent/epoll/kqueue/select等多种事件管理机制,可以根据操作系统版本自由选择合适的管理机制,其中libevent是最优选择的机制。

Redis的网络模型有着所有事件驱动模型的优点,高效低耗。但是面对耗时较长的操作的时候,同样无法处理请求,只能等到事件处理完毕才能响应。所以了解清楚网络模型有助于在业务中扬长避短,减少长耗时的请求,尽可能多一些简单的短耗时请求发挥异步模型的最大的威力。

二.数据结构和内存管理

1.字符串

1.1 内存管理方式

动态内存管理方式,动态方式最大的好处就是能够较为充分的利用内存空间,减少内存碎片化,与此同时带来的劣势就是容易引起频繁的内存抖动,通常采用“空间预分配”和“惰性空间释放”两种优化策略来减少内存抖动,redis也不例外。

每次修改字符串内容时,首先检查内存空间是否符合要求,否则就扩大2倍或者按M增长;减少字符串内容时,内存并不会立刻回收,而是按需回收。

关于内存管理的优化,最基本的出发点就是浪费一点空间还是牺牲一些时间的权衡,像STL、tcmalloc、protobuf3的arena机制等采用的核心思路都是“预分配迟回收”,Redis也是一样的。

1.2 二进制安全

判断字符串结束与否的标识是len字段,而不是C语言的’\0’,因此是二进制安全的。

放心的将pb序列化后的二进制字符串存入redis。

简而言之,通过redis的简单封装,redis的字符串的操作更加方便,性能更友好,并且屏蔽了C语言字符串的一些需要用户关心的问题。

2.字典(哈希)

字典的底层一定是hash,涉及到hash一定会涉及到hash算法、冲突的解决方法和hash表扩容和缩容。

2.1 hash算法

  Redis使用的就是常用的Murmurhash2,Murmurhash算法能够给出在任意输入序列下的散列分布性,并且计算速度很快。之前做共享内存的Local-Cache的需求时也正是利用了Murmurhash的优势,解决了原有结构的hash函数散列分布性差的问题。

2.2 hash冲突解决方法

链地址法解决hash冲突,通用解决方案没什么特殊的。多说一句,如果选用链地址解决冲突,那么势必要有一个散列性非常好的hash函数,否则hash的性能将会大大折扣。Redis选用了Murmurhash,所以可以放心大胆的采用链地址方案。

3.整数集合

变长整数存储,整数分为16/32/64三个变长尺度,根据存入的数据所属的类型,进行规划。

每次插入新元素都有可能导致尺度升级(例如由16位涨到32位),因此插入整数的时间复杂度为O(n)。这里也是一个权衡,内存空间和时间的一个折中,尽可能节省内存。

4.跳跃表

Redis的skilplist和普通的skiplist没什么不同,都是冗余数据实现的从粗到细的多层次链表,Redis中应用跳表的地方不多,常见的就是有序集合。

5.链表

Redis的链表是双向非循环链表,拥有表头和表尾指针,对于首尾的操作时间复杂度是O(1),查找时间复杂度O(n),插入时间复杂度O(1)。

三.AOF和RDB持久化

AOF持久化日志,RDB持久化实体数据,AOF优先级大于RDB。

1.AOF持久化

机制:通过定时事件将aof缓冲区内的数据定时写到磁盘上。

2.AOF重写

为了减少AOF大小,Redis提供了AOF重写功能,这个重写功能做的工作就是创建一个新AOF文件代替老的AOF,并且这个新的AOF文件没有一条冗余指令。(例如对list先插入A/B/C,后删除B/C,再插入D共6条指令,最终状态为A/D,只需1条指令就可以)

实现原理就是读现有数据库的状态,根据状态反推指令,跟之前的AOF无关。同样,为了避免长时间耗时,重写工作放在子进程进行。

3.RDB持久化

SAVE和BGSAVE两个命令都是用于生成RDB文件,区别在于BGSAVE会fork出一个子进程单独进行,不影响Redis处理正常请求。定时和定次数后进行持久化操作。

简而言之,RDB的过程其实是比较简单的,满足条件后直接去写RDB文件就结束了。

四.多机和集群

1.主从服务器

避免单点是所有服务的通用问题,Redis也不例外。解决单点就要有备机,有备机就要解决固有的数据同步问题。

1.1 sync——原始版主从同步

Redis最初的同步做法是sync指令,通过sync每次都会全量数据,显然每次都全量复制的设计比较消耗资源。改进思路也是常规逻辑,第一次全量,剩下的增量,这就是现在的psync指令的活。

1.2 psync

部分重同步实现的技术手段是“偏移序号+积压缓冲区”,具体做法如下:

(1)主从分别维护一个seq,主每次完成一个请求便seq+1,从每同步完后更新自己seq;

(2)从每次打算同步时都是携带着自己的seq到主,主将自身的seq与从做差结果与积压缓冲区大小比较,如果小于积压缓冲区大小,直接从积压缓冲区取相应的操作进行部分重同步;

(3)否则说明积压缓冲区不能够cover掉主从不一致的数据,进行全量同步。

本质做法用空间换时间,显然在这里牺牲部分空间换回高效的部分重同步,收益比很大。

2.Sentinel

本质:多主从服务器的Redis系统,多台主从上加了管理监控,以保证系统高可用性。

原文地址:https://blog.51cto.com/14512197/2446304

时间: 2024-08-05 21:31:55

Redis设计思路总结的相关文章

Redis设计思路学习与总结

版权声明:本文由宋增宽原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/222 来源:腾云阁 https://www.qcloud.com/community 宋增宽,腾讯工程师,16年毕业加入腾讯,从事海量服务后台设计与研发工作,现在负责QQ群后台等项目,喜欢研究技术,并思考技术演变,专注于高并发业务架构的设计与性能优化. 下半年利用空余时间研究和分析了部分Redis源码,本文从网络模型.数据结构和内存管理.持久化和多机

Redis设计与实现(一~五整合版)【搬运】

Redis设计与实现(一~五整合版) by @飘过的小牛 一 前言 项目中用到了redis,但用到的都是最最基本的功能,比如简单的slave机制,数据结构只使用了字符串.但是一直听说redis是一个很牛的开源项目,很多公司都在用.于是我就比较奇怪,这玩意不就和 memcache 差不多吗?仅仅是因为memcache是内存级别的,没有持久化功能.而redis支持持久化?难道这就是它的必杀技? 带着这个疑问,我在网上搜了一圈.发现有个叫做huangz的程序员针对redis写了一本书叫做<redis设

记一次和阿里某总监对话引发的思考:说说你框架的设计思路和优点亮点!

背景: 前不久和阿里的一个技术总监风动聊的时候,他问了这样一个问题:说说你框架的设计思路和优点? 话说,这个问题,5年前开始就一直经常出现在眼前,可我从没认真为它找出过答案! 于是,夜深深,我躺在床上,用笔记本,一边思考,一边打字,试着找寻! 这些年来,我的框架或作品,都快凑满十二个了,每个单独都可以说上好几天. 但如果时间只有半小时,我要怎么介绍呢?介绍哪些呢? 出现在脑海里的框架有三个:CYQ.Data.ASP.NET Aries.Taurus.MVC. 大概是因为近期的精力都在这上面吧的吧

电商 秒杀系统 设计思路和实现方法

电商 秒杀系统 设计思路和实现方法 2017年05月26日 00:06:35 阅读数:3662 1 秒杀业务分析 正常电子商务流程 (1)查询商品:(2)创建订单:(3)扣减库存:(4)更新订单:(5)付款:(6)卖家发货 秒杀业务的特性 (1)低廉价格:(2)大幅推广:(3)瞬时售空:(4)一般是定时上架:(5)时间短.瞬时并发量高: 2 秒杀技术挑战 假设某网站秒杀活动只推出一件商品,预计会吸引1万人参加活动,也就说最大并发请求数是10000,秒杀系统需要面对的技术挑战有: 对现有网站业务造

秒杀的设计思路

电商:如何设计一个秒杀系统 什么是秒杀 秒杀场景一般会在电商网站举行一些活动或者节假日在12306网站上抢票时遇到.对于电商网站中一些稀缺或者特价商品,电商网站一般会在约定时间点对其进行限量销售,因为这些商品的特殊性,会吸引大量用户前来抢购,并且会在约定的时间点同时在秒杀页面进行抢购. 秒杀系统场景特点 秒杀时大量用户会在同一时间同时进行抢购,网站瞬时访问流量激增. 秒杀一般是访问请求数量远远大于库存数量,只有少部分用户能够秒杀成功. 秒杀业务流程比较简单,一般就是下订单减库存. 秒杀架构设计理

主流移动端账号登录方式的原理及设计思路

哈尔滨SEO: 1.引言 在即时通讯网经常能看到各种高大上的高并发.分布式.高性能架构设计方面的文章,平时大家参加的众多开发者大会,主题也都是各种高大上的话题——什么5G啦.AI人工智能啦.什么阿里双11分分钟多少万QPS高并发等等. 但实际上,对于普通的开发者(包括IM开发人员)来说,多数公司.多数团队也都是干着默默无闻.平淡无奇的产品开发,并没有那么多高并发.高大上的事情可以做. 就拿一个IM系统来说,无论你的架构设计考虑了多少分布式.高吞吐.高可用,所有这些事情只要落地,那编码的第一件事情

Pongo网页版JavaScript源代码及设计思路

1.游戏背景介绍(写在前面的废话): 五月初的某天,看到某网推荐了这款游戏,Pongo,看着还不错的样子就用ipad下下来试玩了下,玩了两局感觉还错挺过瘾的,因为是手欠类游戏嘛大家懂的. 但是没一会发现游戏在ipad似乎有些bug,玩一会就会卡住然后只能强退了,真是揪心,记录还等着破呢. 怎么办?玩游戏不如玩自己的游戏的念头又邪恶的出现了,然后就把pad丢给了朋友虐心去,我默默回到电脑前开始动手自己写个不会卡的. 大概两小时吧,写出了基本框架,然后扔sinaapp里试了下效果基本能玩就洗洗睡了.

JS表格分页组件:fupage的设计思路和具体用法(未来考虑开源,争取在2015年)

一.背景         之前在秒针工作的时候,某js高级工程师写了很多自己的组件,其中一套是分页组件,叫做st-grid.不过在我看来,bug太多,我经常给他反馈bug,我也不清楚为啥别人没有发现.    回到武汉工作后,我自己利用业余实践完善自己的官网,从前端到后端,都是自己一个人亲自搞定.    第1个分页的需求是,文章下方的评论,异步加载.第2个需求是,表格管理,比如后台管理系统,经常需要列出user.log等表的记录.   二.实例 <table class="table tab

流程管理中WEB表单开发服务需求分析及设计思路

在流程管理应用中,BPM产品所提供的表单设计工具,主要是面向开发人员的.而一些办公系统产品所提供的表单设计工具,受自身平台限制,无法在大型定制化应用中使用.在此通过对用户需求分析,提出WEB表单开发服务设计思路. 一.需求分析 现如今,在创新与改革社会环境推动下,办公管理系统的管理需求变化已经是常态了,如何让信息系统快速响应支撑管理需求的多变,已经成为使信息化建设和运维人员头痛的事情.特别是在一些大型企事业单位,快速支撑需求更突出.而原有信息系统很难适应这样的需求,必须走创新的路来解决这些需求,