前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >一次失败的面试,复习一次一致性哈希算法

一次失败的面试,复习一次一致性哈希算法

作者头像
乔戈里
发布于 2019-09-18 09:09:35
发布于 2019-09-18 09:09:35
746017
代码可运行
举报
文章被收录于专栏:Java那些事Java那些事
运行总次数:17
代码可运行

本文故事绝对真实,如有雷同,绝对不是巧合! 话说前几天有一次,某大厂的二面。然后呢,烟哥那天刚好有事,所以去不了。于是就约了一场视频面试了!

于是呢,烟哥提前十分钟在公司里头找了一个厕所的坑位,然后进去随手一锁门….(以下省略10000字)…

唉… 我竟然… 我竟然…

我竟然又带薪上厕所了,而且上了一小时!我有罪!

额,是这样的,大厂的厕所是有雅间的。所以环境还马马虎虎,鼻子还是正常的!

OK,交待完背景,然后开始我们的主题!

全局Session

当时的情形是这样的,先介绍一下自己的项目。然后介绍完项目背景以后,因为有一个登陆模块。于是乎有了如下问题

面试官:“先说说全局Session干嘛用的,你们那边全局session是怎么做的?”

这个问题还是很容易的。因为一个应用通常有多台服务器,在登陆成功后,Session只会在其中某一台存储。需要想办法让多台服务器都识别到这个Session,因此才有了这个全局Session的概念。我们用的是后端统一存储的策略,有专门的用户管理系统,上面存储着用户信息以及Session状态。

烟哥注:目前业内在解决全局Sesssion上无外乎四种方法

  • (1)服务端自己进行同步,例如早期的项目,大概是07年那会的(我司老古董项目啊),那会Tomcat的集群能力不行。用的是Weblogic服务器,使用的就是Weblogic的Session复制功能。
  • (2)客户端存储法,将session存储到浏览器cookie中,每次http请求都带session。这里摸着良心坦白说,该方案从没用过,安全性太差。
  • (3)反向代理hash一致性,不需要修改应用代码。修改nginx的配置,保证同一个ip的请求落在同一个web-server上即可。
  • (4)后端统一存储,后端统一找一个中间件将Session存起来即可,这个中间件是数据库或者缓存。

面试官:“那你知道这个平台里Session怎么管理的么?”

必须不知道啊!对我们来说该平台只是一个黑盒,会调接口即可。

于是乎,一个让我头疼的问题出现了!

面试官:“如果让你设计这样一个平台,管理这些Session,你会怎么设计?”

用redis来存储Session,用sessionId作为key,用session当value进行存储。 OK,这时我头脑浮现的架构是这样的

面试官:"如果redis挂了呢?"

咦,这个时候,我突然懵了。面试官到底想问我什么?难道挂了,不是redis从服务器顶上么?这个问题莫非有什么玄机?

然后我是这样答的。 一般情况,主redis挂了,由从redis顶上。如果redis某个slot的主从节点全挂了, 那么我们在rediscluster中有一个配置叫

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cluster-require-full-coverage

当cluster-require-full-coverage为no时,表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用。但是该槽的相关命令不可用。 当cluster-require-full-coverage为yes时,表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群不可用。 该值默认值为yes,也就是集群处于不可用的状态。

这个时候,可能出现了网络中断!

面试官:"你的意思是,redis挂了,整个集群数据就不可用了?"

我回答嗯嗯,是的!

这个时候,面试官

面试官:"你不知道一致性哈希算法么?回去了解一下!"

然后我突然懵了。原来是我想太多,他这样问完,我才get到他问的点。

烟哥注:所以我才说这个面试我有点失败,和面试官不在一个频道上。如果是现场面,可以现场画图,则不会出现这种问题!

面试官想到的架构应该是这样的

上图中,由于有4台服务器(排除从库),因此公式为hash(sessionId) % 4 = 2 ,可知定位到了第2号服务器。

但是呢,普通的如果4台缓存服务器已经不能满足我们的缓存需求,那么我们应该怎么做呢?很简单,多增加几台缓存服务器不就行了!

假设:我们增加了一台缓存服务器,那么缓存服务器的数量就由4台变成了5台。那么原本hash(sessionId) % 4 = 2 的公式就变成了hash(sessionId) % 5 = ?, 可想而知这个结果肯定不是2的,这种情况带来的结果就是当服务器数量变动时,所有缓存的位置都要发生改变!

于是乎,他才想引我去答一致性哈希算法!总之,该死的破网络!导致两边不在一个频道上!

一致性哈希

既然都提到了一致性哈希算法了,就当复习一下吧~~ 一致性哈希算法的精髓只有一个:对2^32次方取模。

我们将二的三十二次方想象成一个圆,这个圆上的数字就是即0~(2^32)-1。 如下图所示

这时候有三台缓存服务器A、B、C。 我们 hash(服务器A的IP地址) % 2^32

插播一下,写到这里,这里我又想起一道题了!

有哪些常见的hash算法啊?

OK,先继续我们的话题。经过上面的运算,我们算出的结果一定是一个0到2^32-1之间的一个整数,我们就用算出的这个整数,代表服务器A,既然这个整数肯定处于0到2^32-1之间,那么,上图中的hash环上必定有一个点与这个整数对应,我们使用这个整数代表服务器A,那么,服务器A就可以映射到这个环上。 同理进行 hash(服务器B的IP地址) % 2^32 hash(服务器C的IP地址) % 2^32

于是,得到了下面这一张图

那么,我们要用服务器存储session,那么我们用sessionId做key,进行如下运算 hash(sessionId) % 2^32 得到的一个环上的值。那我们怎么知道session被存到哪个服务器上呢,OK,顺时针方向找到的第一个服务器就是。如下图所示

假设,我们现在有四个session,分别进行映射运算后得到如下的环

这么做的好处? 使用一致性算法后,当服务器B移除的时候,服务器B上的数据会顺时针移动到服务器C上去。从而避免了当服务器数量发生改变当时候,所有的session都失效。 如下所示

虚拟槽的应用? 真实世界中,服务器可能映射的并不均匀。这就导致了数据可能是下面这样的,大量的数据在A服务器上,导致数据不均匀

为了解决这个问题,我们给A、B、C三台服务器引入虚拟节点。如下图所示(图中黄色节点为虚拟节点)

如图所示,2号session和3号session映射到了虚拟B节点,就会存储到真实的B节点上。通过引入虚拟节点的方式,实现数据的均匀分配!

最后,本文内容全当复习一次一致性哈希算法。希望大家有所收获。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员乔戈里 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
习题3:数字和数学计算
数学运算符号: 1.    +    加号(plus) 2.    -     减号(minus) 3.    /     斜杠(slash) 也叫除号 4.    *     星号(asterisk)也叫乘号 5.    %    百分号(percent)也叫求于 6.    <    小于号(less-than) 7.    >    大于号(greater-than) 8.    <=   小于等于号(less-than-equal) 9.    >=   大于等于号(greater-than-equ
py3study
2018/08/02
4610
html 转义字符常用对照表
字符 十进制 转义字符 描述 @ &#64 &commat at 符号 © &#169 &copy 版权符号 ! &#33 &excl 感叹号 ¡ &#161 &iexcl 倒置感叹号 : &#58 &colon 冒号 , &#44 &comma 逗号 · &#183 &middot 中间点 ‘ &#39 &apos 撇号 ‘ &#8216 &lsquo 左单引号 “ &#8220 &ldquo 左双引号 ( &#40 &lpar 左括号 [ &#91 &lsqb 左方括号 { &#123 &lcub 左花
Savalone
2020/03/13
23.7K0
HTML常用符号
大家好,又见面了,我是全栈君 HTML转义符号 HTML常用符号: 显示一个空格 &nbsp; &#160; < 小于 &lt; &#60; > 大于 &gt; &#62; & &符号
全栈程序员站长
2022/07/15
3.3K0
写作必备的Typora及Markdown语法介绍
” Markdown 是一种轻量级标记语言,创始人是约翰·格鲁伯(John Gruber)。它允许人们 “使用易读易写的纯文本格式编写文档,然后转换成有效的 HTML 文档。”
Java旅途
2021/06/08
5040
程序员英语学习(二) 标点符号对应的英语单词汇总
作为程序员和各种标点字符打交道基本是每天都会经历的,但是不会用英语描述出来也是挺尴尬的,所以我这边汇总以下常用的标点符号,不一定最全,但一定是最符合程序员常用的。
冬夜先生
2021/09/13
1.1K0
HTML转义字符:xss攻击与HTML字符的转义和反转义
转义只是防止xss攻击的一种手段之一,更多请查看:《web开发前端安全问题总结——web前端安全问题汇总》
周陆军博客
2022/06/25
12.2K0
C语言常用的知识没多少之运算符与表达式
在现实中学完数数就要开始学习数的运算,如加减乘除等。C语言也有对数的运算,有算数运算、赋值运算、关系运算、逻辑运算、位运算、条件运算、逗号运算、sizeof运算。在此按照顺序讲解一些常用的运算。
用户5935416
2019/08/01
6350
C语言常用的知识没多少之运算符与表达式
数学建模~~多目标规划
(2)使用上面的这个题目作为例子,简单的翻译一下题干,这个题目说的就是 有1,2这两种产品需要我们进行生产,一共有11的原材料,10小时的时间,产品1的生产消耗原材料2千克,需要耗费1小时,利润是8万元,产品二以此类推;
阑梦清川
2025/02/24
880
数学建模~~多目标规划
【编译原理】词法分析:C/C++实现
编译原理是计算机科学领域的一个重要分支,它研究如何将高级编程语言的源代码转化成计算机能够执行的机器代码或中间代码的过程。编译原理涵盖了编译器的设计和实现,其中编译器是一种将源代码翻译成目标代码的软件工具。编译器的主要任务包括语法分析、词法分析、语义分析、优化和代码生成等环节。
SarPro
2024/02/20
1.9K0
【编译原理】词法分析:C/C++实现
MarkDown 常用语法
最为常用的格式,只需要在文本前面加上 # 即可,同理、你还可以增加二级标题、三级标题、四级标题、五级标题和六级标题,总共六级,只需要增加 # 即可,标题字号相应降低
GoodTime
2024/03/05
1790
MarkDown 常用语法
最常见的Python面试题&答案
ython新手在谋求一份Python编程工作前,必须熟知Python的基础知识。编程网站DataFlair的技术团队分享了一份2018年最常见Python面试题合集,既有基本的Python面试题,也有高阶版试题来指导你准备面试,试题均附有答案。面试题内容包括编码、数据结构、脚本撰写等话题。
程序员鑫港
2021/12/22
8590
Java基础学习笔记二 Java基础语法
对于单行和多行注释,被注释的文字,不会被JVM解释执行;对于文档注释,可以被JDK提供的工具javadoc 所解析,生成一套以网页文件形式体现的该程序的说明文档;单行注释可以嵌套使用,多行注释不能嵌套使用。
緣來
2020/01/02
6220
Java基础学习笔记二 Java基础语法
PL/0语言编译程序分析
  PL/0语言是Pascal语言的一个子集,我们这里分析的PL/0的编译程序包括了对PL/0语言源程序进行分析处理、编译生成类PCODE代码,并在虚拟机上解释运行生成的类PCODE代码的功能。   PL/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。词法分析和代码生成作为独立的子程序供语法分析程序调用。语法分析的同时,提供了出错报告和出错恢复的功能。在源程序没有错误编译通过的情况下,调用类PCODE解释程序解释执行生成的类PCODE代码。   词法分析子程序分析:   词法分析子程序名为get
逍遥剑客
2018/05/21
1.8K0
可以直接用于HTML中的特殊字符表 unicode字符集
目录 箭头类 基本形状类 货币类 数学类 音乐符号类 对错号 全都是星星 星座类 国际象棋类 扑克牌类 希腊字母 十字 法律符号 标点和符号 ⇠ 箭头类 符号UNICODE符号UNICODEHTMLJSCSSHTMLJSCSS⇠&#8672u21E021E0⇢&#8674u21E221E2⇡&#8673u21E121E1⇣&#8675u21E321E3↞&#8606u219E219E↠&#8608u21A021A0↟&#8607u219F219F↡&
拿我格子衫来
2022/01/24
2.9K0
python基础语法(1)
从今天起,将进行python的一个系列学习,从基本的语法学起,后期会推出一些关于web开发,网络爬虫以及用python的第三方库进行数据挖掘与机器学习等高级的开发应用,敬起期待~欢迎转发 Python的特点   1. 简单     Python是一种代表简单思想的语言。   2. 易学     Python有极其简单的语法。   3. 免费、开源     Python是FLOSS(自由/开放源码软件)之一。   4. 高层语言     使用Python编写程序时无需考虑如何管理程序使用的内存一类的底层细节。
昱良
2018/04/04
1.1K0
Python 基础语法(一)「建议收藏」
    Python已被移植到很多平台,这些平台包括Linux、Windows、FreeBSD、Macintosh、Solaris、OS/2、Amiga、AROS、AS/400、
全栈程序员站长
2022/09/07
6310
6.QT-简易计算器实现(详解)
界面展示 image.png image.png image.png 1.用户界面类设计 需要使用QWidget组件作为顶层窗口,QLineEdit组件作为输入框,QPsuhButton作为按钮 1.1 在代码里处理按键消息时,需要处理下用户输入的格式(方便逻辑模块计算) 1)匹配括号成对出现,左括号必然先于右括号出现 当有左括号出现时,则status++ 当有右括号出现时,并且status!=0时,则右括号有效,并status--   2)判断每个按键是否合法 数字前面不能为:右括号 比如: 10+
诺谦
2018/05/28
2.4K0
MarkDown表情符号码与基本语法
Emoji表情 将对应emoji表情的符号码复制后输入你的markdown文本即可显示emoji表情。 如:blush:,显示为😊 人物 syntax preview syntax preview syntax preview :bowtie: :bowtie: :smile: 😄 :laughing: 😆 :blush: 😊 :smiley: 😃 :relaxed: ☺️ :smirk: 😏 :heart_eyes: 😍 :kissing_heart: 😘 :kissing_closed_eyes: 😚
MinChess
2022/12/26
3.6K0
[Mac 技巧]如何在Mac OS X里输入特殊字符?
常见的特殊符号,在mac中怎么输入?见下面: 苹果标志 (Shift+Option+K) Copyright © (Option+G) 美元 $ (Shift+4) 美分 ¢ (Option+4) 英镑 £ (Option+3) 日元 ¥(Option+Y) 欧元 €(Shift+Option+2) 破折号 –(Option+-) 约等于 ≈(Option+X) 度 °(Shift+Option+8) 除号 ÷(Option+/) 循环 ∞(Option+5) 小于等于≤(Option+,) 大于等于≥(
EltonZheng
2021/01/26
8360
常用特殊符号的HTML代码(HTML字符实体)
ISO-8859-1 的较低部分(从 1 到 127 之间的代码)是最初的 7 比特 ASCII。
用户5640963
2019/07/26
10.2K0
相关推荐
习题3:数字和数学计算
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档