幂等设计

请求幂等性总结:

1.是否需要幂等。比如查询,insert含唯一索引的表,update set数据,delete by id 等简单场景是天然幂等。不需要额外做幂等操作。无法这样的比如要做数据的累加,就要做幂等。

2.如何判断重复。

业务唯一键,查记录表或流水表,根据记录的有无和状态来判断。

3.实现。

  1. 简单的话接口直接实现, 但通常幂等逻辑是有通用性的
  2. 如果服务多接口使用写幂等工具类
  3. 如果多服务使用一套幂等逻辑,写sdk
  4. 最复杂的多服务间幂等,还无法都获取到记录结果,就要在sdk统一读写幂等表,读写相同的幂等记录做幂等

4.并发处理

  1. 单机情况下,使用java锁synchronized
  2. 使用数据库锁,悲观锁:select for update,乐观锁:update set XXX and version = 2 where version = 1
  3. 使用分布式锁:
    redis锁:1.过期时间导致并发问题,2.主从切换时锁丢失
    zookeeper锁:写能力不如redis

原文:

  1. 维度1 : 是否需要幂等处理?

    1. 查询场景

      select 字段 from 表 where 条件 ,这种是不会对数据产生任何变化,所以查询场景具备天然幂等性;注意这里的幂等是对系统资源的改变,而不是返回数据的结果,即使返回结果不相同但是该操作本身没有副作用,所以幂等

    2. 新增场景

      insert into 表 (order_id,字段) value(1,字段) :

      1)如果order_id为唯一键,重复操作上面的业务,只会插入一条数据,具备天然幂等性。

      2)如order_id不是唯一键,那上面业务多次操作,数据都会新增多条,不具备幂等性。

    3. 修改场景

      1)直接赋值场景:update 表 set price = 20 where id=1 ;分析: 这种场景不管执行多少次,price都一样,具备天然幂等性;

      2)计算赋值场景:update 表 set price = price + 20 where id=1,每次操作price数据都不一样,不具备幂等性;

    4. 删除场景

      1)delete from 表 where id=1 ,多次操作,结果一样,具备天然幂等性

      2)delete from 表 where price > 20,多次操作,结果一样,具备天然幂等性

      总结:单纯的查询接口,删除接口,没有计算的更新接口,每次执行结果是天然幂等的,其他情况则可能需要做幂等

  2. 维度2 : 是否需要并发控制?

    1. 场景1: 唯一键数据的重复插入

      此场景不需要并发控制,天然并发安全,但需要业务方处理DuplicateKeyException异常

    2. 场景2:转账,若 a >= 100, a -100, b+100

      此场景为了保证数据一致性,事务原子性,需要顺序执行

      总结:除了极其简单的场景外,大部分幂等场景都需要并发控制,需要强锁还是弱锁

  3. 维度3 : 如何判断是重复请求?

    1. 场景1: 无业务主键的新增

      此场景下需要服务端颁发token,通过token判断是否重复,做防重复提交

    2. 场景2: 有业务唯一键的新增

      此场景下可以使用业务唯一键判断是否重复

    3. 场景3: 有业务唯一键的更新

      此场景下可以使用业务数据对应的状态判断是否重复

  4. 维度4 : 重复请求处理方式?

    1. 场景1:消息重复消费

      此场景下,不需要给上游一个返回,重复执行只需要丢弃

    2. 场景2:前端重复提交

      此场景下,需要给用户一个提示,那么重复请求可以直接抛出一个DuplicateReqeustException异常,由上层捕获,前端展示“请不要重复请求”

    3. 场景3: 底层的转账接口

      此场景下,同一笔转账,重复调用第一次若成功了,第二次应该返回相同“成功”,若第一次失败了,第二次返回业务执行结果

      结论:根据不同场景,应该有不同的结束方式,应该由业务方自己决定是丢弃,抛异常,直接返回,还是执行业务逻辑

  5. 维度5 : 重复请求返回是否相同?

    1. 场景1:第一次执行成功,第二次返回应该与第一次相同

    2. 场景2:第一次执行因为代码原因导致的异常而失败,第二次返回应该与第一次相同

    3. 场景3:第一次执行因为网络原因失败,第二次应该执行业务逻辑,返回结果可能不一致

      总结:根据第一次执行的成功和失败,判断第二次应该执行业务逻辑还是直接返回相同结果

  6. 维度6 : 重复请求调用下游如何处理?

    1. 场景1: 业务逻辑中,有调用下游rpc接口,第一次执行失败,第二次重复执行业务逻辑再次调用下游接口

      总结:此场景本质上是一个分布式一致性问题,需要业务方自己解决,或者保证下游接口也是幂等的

  7. 识别相同请求

    1. token机制:每次提交上来的请求,都带上一个token标识,同一个token只处理一次,例如:新增场景的防止重复提交
    2. 业务唯一标识:使用id或者unique key,例如:支付后,支付凭证落库
    3. 业务唯一标识 + 状态:支付后,通过支付凭证号和当前订单状态,更新订单状态
    4. 在业务侧建立同库幂等数据表,记录请求唯一键和执行状态,执行成功后更新状态为成功
  8. 并发处理方式

    1. 单机情况下,使用java锁synchronized

    2. 使用数据库锁,悲观锁:select for update,乐观锁:update set XXX and version = 2 where version = 1

    3. 使用分布式锁:

      redis锁:1.过期时间导致并发问题,2.主从切换时锁丢失

      zookeeper锁:写能力不如redis

  9. 一致性保证

    1. 业务方需保证原子性,本地更新都在一个事务里
    2. 若无法保证分布式事务,下游接口需是幂等的,且本地事务必须重试达到最终一致

SDK设计#

  1. 并发控制
    1. 提供注解,按业务自动划分,提供指定幂等唯一键
    2. 提供并发控制,分布式锁服务(redis或zk),指定分布式锁时间
    3. 提供并发时幂等处理方式,丢弃/抛异常/等待锁
    4. 提供降级选择,不强依赖于锁服务
    5. 提供token注解,防止重复提交
  2. 判断重复请求

处理方式 优点 缺点

方案一 业务方自己判断 业务方需要自己考虑判重

方案二 sdk提供判重接口,由业务方实现 可以实现重复请求的通用处理

方案三 幂等表:在业务侧建立同库幂等数据表,记录请求唯一键和执行状态,执行成功后更新状态为成功 业务方无需再关心判重问题 数据量大,开发量大,复杂度较高

缓存穿透、击穿、雪崩

缓存穿透#

定义: 访问一个不存在的key,缓存不起作用,请求会穿透到DB,流量大时DB会挂掉。

解决方案:

  1. 缓存空值 (值少时)
  2. 布隆过滤器, 特性: 没有的肯定没有,有的不一定有

缓存击穿#

定义:并发性,一个存在的key,在缓存过期的一刻,同时有大量的并发请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。

解决方案:

  1. 分布式锁,在访问key之前,采用分布式锁SETNX(set if not exists)来设置另一个短期key来锁住当前key的访问,访问结束再删除该短期key

缓存雪崩#

定义:大量的key设置了相同的过期时间,或者某台服务器宕机,导致大量缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。

解决方案:

  1. 将key的过期时间设置时添加一个随机时间,分散过期时间
  2. 如果是热点key,可以加分布式锁,减少并发量
  3. 二级缓存(本地缓存),减少db压力

2019国庆上海苏州四日游记

9月30日 外滩 很久以前羊肉串#

接到小菜猫,先去旅馆放下东西,直接去外滩。 南京东路上都是武警,维持秩序,看着有点厉害。我是第二次来外滩,小菜猫是第一次,还是很好看的,人很多,当晚有灯光表演,30分钟一次,我们赶上了一半。海风很舒服。整个外滩的爱国氛围也很浓厚。

外滩

去吃了很久以前羊肉串,吃到晚上12点多,羊肉真的好嫩,当面烤也是特色,配上啤酒,舒服,长肉。

10月01日 武康路#

武康路没有拍什么照片,是一条安静古老的小路,下着小雨,氛围很好

在这里出发去世界上最大的星巴克

一栋星巴克,里面两层。点了一杯奶和一杯咖啡。没有太好喝但环境很好,主要咖啡☕️咱也不懂。里面有些机器在做咖啡,全流程透明化。

下午5点多了,风雨越来越大,继续出发,去豫园&城隍庙,但到了之后风雨太大,也没找到豫园在哪,哈哈,就转地铁回去了。

晚上去吃了和府捞面,办了会员,赠了个虾,嚯,真虾(瞎)

10月2日 蟹面 诚品书店 金鸡湖#

上午出门去吃蟹面,尴尬的是行李太沉,不该带着行李去吃,不过蟹面还是很不错,从没吃过这样式儿的,带汤的那碗很不错,人超级多,排了好一会儿

出发去苏州~

上海到苏州也太快了,半个小时就到了,小菜猫睡了一会儿,我还没睡就到了,放下行李先奔了金鸡湖

诚品书店太安静了,没怎么拍照片,金鸡湖还是很美的,毕竟北方湖还是很少的。见到漂亮的湖,小风一吹,还是很爽。

美美哒

晚上吃了高级台湾自助火锅,到了才发现是自助,不过还是靠实力吃回来了。

10月3日 怡园 留园#

上午要去留园,然后我拉肚子,耽误了坐车,就先去了怡园,没想到怡园还不错,后来发现留园反而因为人多,毫无观赏体验。

怡园

留园就不放了,人太多了,下次不去那么多人的地方了。。

10月4日 归途#

沿途的风光也不错,回家啦

2019国庆上海苏州四日游行程计划

2019 国庆上海苏州四天旅行#

行程规划#

北京前往上海 9.30 14:10 - 20:09 G141 检票口 11

9月30日#

住宿 上海家荣酒店公寓(中山公园店)
21点 很久以前羊肉串(中山公园店)

10月1日#

上午 9点
武康路
上午 11点
田子坊
下午1点
豫园&城隍庙 ,明朝时期的私人花园,拥有“城市山林”、“奇秀甲于东南”两种美称,是江南园林中的一颗明珠。
下午4点
东方明珠
南京路步行街
下午7点半
外滩 外滩观光隧道

10月2日#

上午9点
中华艺术宫
上午12点
退房
下午14:41 上海前往苏州 14:41 - 15:15 D3010 检票口 25A
住宿 骏怡连锁酒店
下午4点半
诚品书店
金鸡湖
阳澄湖大闸蟹

10月3日#

上午9点
拙政园
苏州博物馆
下午1点
虎丘
留园
网师园夜景

10月4日#

苏州前往北京 10.4 11:40 - 17:10 G128 检票口 A1

springioc初始化

IOC 容器的初始化过程分为三步骤:Resource 定位、BeanDefinition 的载入和解析,BeanDefinition 注册

1.Resource 定位。我们一般用外部资源来描述 Bean 对象,所以在初始化 IOC 容器的第一步就是需要定位这个外部资源。

2.BeanDefinition 的载入和解析。装载就是 BeanDefinition 的载入。BeanDefinitionReader 读取、解析 Resource 资源,也就是将用户定义的 Bean 表示成 IOC 容器的内部数据结构:BeanDefinition。在 IOC 容器内部维护着一个 BeanDefinition Map 的数据结构,在配置文件中每一个都对应着一个BeanDefinition对象。

3.BeanDefinition 注册。向IOC容器注册在第二步解析好的 BeanDefinition,这个过程是通过 BeanDefinitionRegistery 接口来实现的。在 IOC 容器内部其实是将第二个过程解析得到的 BeanDefinition 注入到一个 HashMap 容器中,IOC 容器就是通过这个 HashMap 来维护这些 BeanDefinition 的。在这里需要注意的一点是这个过程并没有完成依赖注入,依赖注册是发生在应用第一次调用 getBean() 向容器索要 Bean 时。当然我们可以通过设置预处理,即对某个 Bean 设置 lazyinit 属性,那么这个 Bean 的依赖注入就会在容器初始化的时候完成。

记录租房第三个住处-天通苑东三区

上上周末8月24号搬到了新的租房,搬到了天通苑北一区,换了一居,也住了十几天了,感觉很不错,但之前的租房也很好,它有一个大大的天台,还可以上房顶,把照片记录下来。

上周末回去稍微收拾了下屋子,卖了东西,图中为美丽聪慧的对象

客厅兼卧室

很大的地方还有个落地灯

厨房以前在这个地方,这个屋在之前一段时间我们都把垫子搬过来打地铺睡,因为有一天我发现这里比较隔猫

我的电脑桌放在这个地方

大大的厕所,目前住过最大厕所

小储藏室

通往天台的门,lily最爱去的地方,总是会在这个地方站好开叫,然后看你过来了就扒扒门,lily非常渴望自由,想出去玩

出来啦!

有一圈的天台,第一次见时真的很惊喜

视野十分开阔,夕阳西下,喝酒吃肉,美滋滋

在小区里捡到了很能叫又贪吃的新家庭成员,小 jojo

开始小小的很可爱,

陪我玩电脑

写博客

要抱抱

举高高

与lily从打闹慢慢有点和谐相处

学lily睡窗台

和我们一起睡觉,四生物一张床

后来因为早上太闹,用梳妆台挡住这两个捣蛋鬼,jojo此时已显猪态

幸福生活未完待续..

rss订阅

使用 feedly 订阅 rss,实现多设备同步

教程:https://techmoon.xyz/feedly/

目前导出的我的订阅源, Feedly订阅.opml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?xml version="1.0" encoding="UTF-8"?>
<opml version="2.0">
<head>
<title>Feedly订阅</title>
</head>
<body>
<outline title="NBA" text="NBA">
<outline text="千年孤寂 的 Youtube 视频" title="千年孤寂 的 Youtube 视频" xmlUrl="https://rsshub.app/youtube/channel/UC6QUkl7S6AYwkpQFhmdFIoQ" type="rss" htmlUrl="https://www.youtube.com/channel/UC6QUkl7S6AYwkpQFhmdFIoQ" />
<outline htmlUrl="https://space.bilibili.com/184687394/#/article" title="听说不怕肚子疼 的 bilibili 专栏" type="rss" text="听说不怕肚子疼 的 bilibili 专栏" xmlUrl="https://rsshub.app/bilibili/user/article/184687394" />
</outline>
<outline text="产品" title="产品">
<outline title="李自然说 的 bilibili 空间" xmlUrl="https://rsshub.app/bilibili/user/video/39089748" type="rss" htmlUrl="https://space.bilibili.com/39089748" text="李自然说 的 bilibili 空间" />
<outline htmlUrl="https://post.smzdm.com/hot_7" type="rss" xmlUrl="https://rsshub.app/smzdm/haowen/7" text="周热门-什么值得买好文" title="周热门-什么值得买好文" />
<outline xmlUrl="http://fz0512.com/feed" text="最好金龟换酒" title="最好金龟换酒" htmlUrl="http://fz0512.com" type="rss" />
<outline title="少数派" text="少数派" htmlUrl="https://sspai.com" xmlUrl="http://sspai.com/feed" type="rss" />
<outline text="V2EX-最热主题" xmlUrl="https://rsshub.app/v2ex/topics/hot" title="V2EX-最热主题" type="rss" htmlUrl="https://www.v2ex.com/" />
<outline title="微信公众号 - 一本黑" text="微信公众号 - 一本黑" xmlUrl="https://rsshub.app/wechat/csm/darkinsider" type="rss" htmlUrl="https://chuansongme.com/account/darkinsider" />
</outline>
<outline text="图片" title="图片">
<outline title="国家地理每日一图" text="国家地理每日一图" type="rss" htmlUrl="https://www.nationalgeographic.com" xmlUrl="https://feedx.co/rss/nationalgeodayphoto.xml" />
</outline>
<outline title="好友" text="好友">
<outline title="大菜猫" htmlUrl="https://www.techwei.cn/" text="大菜猫" xmlUrl="https://techwei.cn/atom.xml" type="rss" />
<outline htmlUrl="https://jacobchang.cn/" text="黄小豆的博客" title="黄小豆的博客" type="rss" xmlUrl="https://jacobchang.cn/atom.xml" />
<outline xmlUrl="https://rsshub.app/bilibili/user/video/11036610" text="爱浪的黄小豆 的 bilibili 空间" type="rss" title="爱浪的黄小豆 的 bilibili 空间" htmlUrl="https://space.bilibili.com/11036610" />
<outline htmlUrl="https://www.yuanqiongqiong.cn/" title="袁琼琼的博客" xmlUrl="http://yuanqiongqiong.cn/atom.xml" text="袁琼琼的博客" type="rss" />
</outline>
<outline text="技术" title="技术">
<outline xmlUrl="https://rsshub.app/juejin/category/backend" type="rss" text="掘金后端" title="掘金后端" htmlUrl="https://juejin.im/welcome/backend" />
<outline type="rss" text="美团技术团队" htmlUrl="https://tech.meituan.com/feed/" xmlUrl="https://rsshub.app/meituan/tech/home" title="美团技术团队" />
<outline htmlUrl="http://www.ruanyifeng.com/blog/" xmlUrl="http://www.ruanyifeng.com/blog/atom.xml" title="阮一峰的网络日志" type="rss" text="阮一峰的网络日志" />
<outline htmlUrl="https://chuansongme.com/account/importnew" type="rss" xmlUrl="https://rsshub.app/wechat/csm/importnew" text="微信公众号 - ImportNew" title="微信公众号 - ImportNew" />
<outline title="微信公众号 - 一本黑" type="rss" text="微信公众号 - 一本黑" htmlUrl="https://chuansongme.com/account/darkinsider" xmlUrl="https://rsshub.app/wechat/csm/darkinsider" />
</outline>
<outline text="新闻" title="新闻">
<outline xmlUrl="https://rsshub.app/gov/zhengce/zuixin" type="rss" text="最新政策 - 中国政府网" title="最新政策 - 中国政府网" htmlUrl="http://www.gov.cn/zhengce/zuixin.htm" />
</outline>
<outline text="生活" title="生活">
<outline text="美国日记" title="美国日记" type="rss" htmlUrl="http://cn.derekyang.us" xmlUrl="http://cn.derekyang.us/?feed=rss2" />
<outline text="人生不过如此" htmlUrl="http://nana.blog.paowang.net" title="人生不过如此" xmlUrl="http://nana.blog.paowang.net/feed/" type="rss" />
</outline>
<outline title="电影" text="电影">
<outline htmlUrl="https://www.douban.com" type="rss" xmlUrl="https://feedx.co/rss/doubanmvweek.xml" text="豆瓣电影本周口碑榜" title="豆瓣电影本周口碑榜" />
<outline text="MovieTalk-电影七日谈 的 bilibili 空间" title="MovieTalk-电影七日谈 的 bilibili 空间" xmlUrl="https://rsshub.app/bilibili/user/video/10869763" htmlUrl="https://space.bilibili.com/10869763" type="rss" />
</outline>
<outline title="艺术" text="艺术">
<outline type="rss" htmlUrl="http://bing.com" text="必应今日美图" title="必应今日美图" xmlUrl="https://feedx.co/rss/bingwallpaper.xml" />
</outline>
</body>
</opml>
</opml>

读《自控力》

前言#

看了本周”李自然说”讨论学习方法,里面有一句话非常喜欢,人和人的差距大于人和猪的差距。

这句话夸张的表达了人和人的差距会有多大,人和人理解问题的深度、处事的态度、说话的逻辑和好听程度,有趣指数,相信大家都想做人上人,百里挑一的人,不止是为了获得更多的财富,更是让自己的生活满意,做事情处事不惊,游刃有余。 今天开始阅读《自控力》,不是说这一本书能带我走向人生巅峰,只希望是个好的开始。

01 意志力是什么,为什么至关重要#

###意志力

就是驾驭 “我不要”, “我要做”,”我想要” 这三种力量。

“我不要” : 抵制诱惑!#

抵制甜甜圈,香烟,清仓大甩卖,或一夜情等等很诱人的东西,这些东西阻碍你实现你真正想要的,比如瘦身,好的肺,幸福的家庭等,如果你一面对就会无法抵抗,那就要提升意志力,提升“我不要”的能力。

这些东西可能会带来即时的快感,但只是因为真正美好的东西暂时离你远,因为时空的距离感,让你选择了当前的选项,但如果思维清晰,目标明确,就不要为眼前的小利益而放弃大目标。

比如你想换工作、换城市,考虑清楚之后,知道换了之后的结果是好的,但过程中有困难和安逸给你选,如果选了安逸,就是当前的诱惑赢了,如果选了困难,就是意志力的体现,对当前诱惑说出 “我不要” !

“我要做” :今日事今日毕 !#

“明日复明日”,拖延症晚期患者有些事情可能拖到下辈子再做,是这部分意志力薄弱,我理解不可能每天真毕,但“做” 和 “拖”的差距是很大的,是“我要做”意志力的体现。

“我想要”: 真正要的是什么!#

当我们在冲动的时候有时会觉得这就是自己想要的,想要玩游戏、想要喝酒、巧克力蛋糕、骂人等等,但一定得想清楚,你真正要的是什么样的身材,什么样的素养,什么样的生活,是否希望苗条、升职加薪、家庭美满,是否吃”巧克力蛋糕”, 吃多少,要在关键时刻遏制住一时冲动,明确自己的目标,强大的目标明确能力,是“我想要”意志力的体现。

小总结#

个人理解意志力的体现肯定不是要让我们当机器人或当狗(加班狗、奋斗狗),而是像某口号一样,集中力量办大事,只是集中的是自己的力量,办的是“我想要”的事。

两个自我#

大脑中有两个部分,一部分是控制自己,一部分是冲动的自己。冲动为原始的冲动,我们的本能; 控制自己的就是我们的前额皮质。

“两个自我发生分歧的时候,总会有一方击败另一方。决定放弃的一方并没有做错,只是双方觉得重要的东西不同而已。”

原始的本能冲动是我们必不可少的,没有欲望,人就会变得沮丧,没有恐惧,就没法保护自己,没有厌恶,就没法提高自己,我们不是要消灭冲动的自己,而是要学会利用冲动的自己,换句话就是在合适的时候冲动,合适的时候控制。

原始的冲动带着自己进步,而当冲动要带我们走向错误的时候,控制自己的能力需要体现。

自我意识#

自我意识体现在做决定的时候,意识到要做自己的选择,生活才是自己的。

这里重点是意识到自己可以做的选择。一件事,我根据自己的想法做出选择,是自我意识,而我如果没思考,下意识走了简单舒适的选择时,就是自我意识的缺失,一种随波逐流,这样选的结果不一定不好,但不会一直是自己想要的。

做一个有自我的人

冥想#

冥想通过坐着闭眼专注于”呼“ ”吸“, 锻炼自己的控制能力,注意力集中能力,意志力。

冥想我相信对应现实中的注意力集中能力,自控能力都会有一定提升。

今天进行了人生第一次冥想,虽然大部分时间都无法专注于呼吸,但我看到了挑战,当我能完全专注于呼吸的时候,那我的集中注意力的能力就会变得很强。

mark一篇完整冥想步骤文章

https://mp.weixin.qq.com/s/2nV2u66ScuLJEHEXcrHkMQ

策略模式

redis单线程还这么快

为什么Redis使用单线程模型会达到每秒万级别的处理能力呢?可以将其归结为三点使Redis具有很高的吞吐量?#

1. 纯内存访问#

Redis将所有数据放在内存中,内存的响应时长大约为100纳秒,这是Redis达到每秒万级别访问的重要基础。

纯内存数据库,如果只是简单的 key-value,内存不是瓶颈。一般情况下,hash 查找可以达到每秒数百万次的数量级。瓶颈在于网络 IO 上。每次请求需要通过网络把请求发送到 redis 所在的机器,然后等待 redis 返回数据。时间大部分消耗在网络传输中。如果把 redis 和客户端放在同一台机器,网络延迟会更小,一般情况下可以打到 60000 次每秒甚至更高,取决于机器性能。

2. I/O多路复用、事件驱动模型#

旨在解决IO的问题。多路I/O复用模型是非阻塞IO,内部实现采用epoll和自己实现的事件分离框架。

其利用select、poll、epoll 可以同时检测多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。

“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗)。

总结就是Redis使用epoll作为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间,如下图所示。

3. 单线程避免了线程切换和竞态产生的消耗。#

线程模型#

主线程#

其它#

  1. Redis会fork得到的子进程,用来处理RDB持久化以及AOF持久化等任务

  2. 一组异步任务处理线程,即Redis异步化组件——BIO组件

BIO组件目前包括三个线程,分别处理三种类型的任务:
1)文件句柄关闭任务
2)AOF持久化任务
3)空间懒释放

持久化#

Redis 提供了两种持久化策略

RDB 持久化机制,会在一段时间内生成指定时间点的数据集快照(snapshot)

AOF 持久化机制,记录 server 端收到的每一条写命令,当 server 重启时会进行重放以此来重建之前的数据集。AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加(append)到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite) ,使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。

如果你仅使用 Redis 作为缓存加速访问,你可以关闭这两个持久化设置

你也可以同时开启这两个持久化设置,但是在这种情况下,Redis 重启时会使用 AOF 文件来重建数据集,因为 AOF 文件保存的数据往往更加完整

单线程利弊#

单线程模型能带来几个好处:
第一,单线程可以简化数据结构和算法的实现。并发数据结构实现不但困难而且开发测试比较麻烦。
第二,单线程避免了线程切换和竞态产生的消耗,对于服务端开发来说,锁和线程切换通常是性能杀手。

但是单线程会有一个问题:
对于每个命令的执行时间是有要求的。如果某个命令执行过长,会造成其他命令的阻塞,对于Redis这种高性能的服务来说是致命的,所以Redis是面向快速执行场景的数据库。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×