hash

Redis 集群

半世苍凉 提交于 2020-04-06 12:25:36
想到一句很搞笑的话:“为什么要用集群呢,单机不香吗?”。确实,为什么要选择集群呢?大概都是从两个角度来考量的: 提高系统的可用性,单点故障是任何系统的灾难。 提高系统的高性能,单台计算机的处理能力肯定是有限的。 Redis 集群是如何实现的呢?我比较吃惊的是,集群中提供服务的都是 Master 节点,每个节点都负责一部分槽位。在整个集群中,数据是根据槽位来存储的,总共有16384个槽位。 客户端操作一个 Key ,如何定位它要写到哪个槽位上呢?其实也是一个哈希处理算法: CRC16(Key) & 16384 对比我们经常使用的 HASH 、一致性 HASH , Redis 集群引入了槽位。 HASH 算法都是直接通过元素来计算,应该跟哪一个节点来进行交互。但 Redis 集群在两者之间又引入了槽位。 元素Key -> Hash计算槽位 -> 确定集群中的节点 问题来了,对于诸如 MSET 这种命令,它会同时设置多个 Key ,集群如何处理这种情况呢?集群引入了 HASH Tag 来辅助我们:通过只计算 HASH Tah 中的部分来计算槽位: // 只计算{}中的部分来确定槽位 {comment:repost}note {comment:repost}user 如果没有特殊处理,客户端的请求肯定不知道具体应该跟哪一个 Redis 节点打交道。比如存在两个节点,且它们负责的槽位如下:

一致性hash 的简单理解

半世苍凉 提交于 2020-04-06 12:19:53
比如我们原来的负载均衡算法是对服务器提供者可以提供的数量取余 这样存在的一个弊端,就是新加或删除一个节点,需要重新计算hash的落点 原来的落点就失效了 比如:原先hash(ip) % 3 ,后来hash(ip) % 4 这种的通用解决方案是改用链环 , 当我们对一个A值,算它对应的机子时,就是对2^32 进行取余,得到落点,然后顺时针命中一个机子 我们看下添加一个机子的情况 这样仅仅只是将原来落点到ip3的一部分数据改为落点到ip4,其余的并没有影响。删除也是一样的道理 这就是一致性hash的好处 下面介绍下一致性hash 的特点 1,平衡性 (Balance) : , 2, 分散性 (Spread) 当然这样直接对ip进行hash可能存在数据倾斜问题。我们可以通过添加虚拟节点来解决此问题 来源: oschina 链接: https://my.oschina.net/u/3574106/blog/3213248

哈希、哈希表详解及应用

本小妞迷上赌 提交于 2020-04-06 07:02:42
前置概念 Key : 我们提供的一个要进行哈希的数字 \(f(x)\) :即为哈希函数,将key扔到这个函数里面,可以得到Value,最核心的构造哈希表的东西 Hash地址:hash出来的值在哈希表中的存储位置 进入正题 字符串hash 例题1:【模板】KMP 现有T组数据,每次给定两个字符串 \(s1\text{和}s2\) ,求 \(s1\text{在}s2\) 中出现了几次。 首先考虑的当然是KMP了(逃 但是由于我们讲的是字符串hash,那就考虑怎么用字符串hash求解; 考虑每次枚举每一个子串的hash值,但是复杂度..... \(O(nm)\) 所以介绍一个优化技巧:滚动hash 滚动hash 滚动hash的诞生就是为了避免在 \(O(m)\) 的时间复杂度内计算一个长度为m的字符串的hash值: 我们选取两个合适的互质常数(虽然不知道为什么互质)b和h,对于字符串c,我们搞一个hash函数: \(hash(c)=(c_1b^{m-1}+c_2b^{m-2}+.....+c_mb^0)mod h\) 这个hash函数的构造过程是以递推实现的,设 \(hash(c,k)\) 为前k个字符构成的子串的hash值,有 \(hash(c,k)=hash(c,k-1)\times b+c_{k}\) 为方便理解,设 \(c="ABCD"\) 且 \(A=1,B=2....\) 则

字符串哈希

会有一股神秘感。 提交于 2020-04-06 06:00:53
转 http://acm.uestc.edu.cn/#/problem/show/1092 韩爷的梦 Time Limit: 200/100MS (Java/Others) Memory Limit: 1300/1300KB (Java/Others) Submit Status 一天,韩爷去百度面试,面试官给了他这么一个问题。 给你2万个字符串,每个字符串长度都是100,然后把2万个字符串丢入一个 set< string >g 中,问最终set里含有多少个元素? g 是一个用来存储字符串、具有去重功能的容器,即相同字符串在 g 中只能保留一个。 两个字符串相等,当且仅当,长度一样且对应位置的字符都一样。 韩爷前晚没睡好,随手写了一个程序交给面试官,然后就gg了。 #include<iostream> #include<string> #include<set> using namespace std; string s; set<string>g; int main(){ for(int k=1;k<=20000;k++){ cin>>s; g.insert(s); } cout<<g.size()<<endl; return 0; } 韩爷醒来之后,发现这只是一个梦(还好只是个梦)。他回忆起梦中的面试官给他的内存限制和时间限制非常低,这么做肯定过不了,那么,现在你不在梦中

HASH 字符串哈希 映射转化

二次信任 提交于 2020-04-06 05:41:49
哈希HASH的本质思想类似于映射、离散化。 哈希,通过给不同字符赋不同的值、并且钦定一个进制K和模数,从而实现一个字符串到一个模意义下的K进制数上。 它的主要目的是判重,用于$DFS$、$BFS$判重(八数码),字符串判断相等、出现等等。 本篇总结字符串哈希以及一些应用例题。 为什要用字符串哈希? 因为取出一个字符串是$O(n)$的,比较一遍又是$O(n)$的,况且要比较两个甚至多个。这就成了$n^2$级别的了。 那我们比较数字怎么就不用这么麻烦呢?因为数字可以直接比较,(虽然不知道内部是怎么实现的,反正比一位一位比较肯定快)所以我们考虑把字符串映射到数字上。 就有了字符串哈希。 通过字符串哈希,只要题目支持预处理,我们可以$O(n)$预处理之后,$O(1)$进行提取,$O(1)$进行判重。 字符串哈希需要什么? 1.字符。初始坐标无所谓。 2.K进制数,通常选择$131$,$13331$,这两个质数冲突几率很小 (不要问我为什么) 。 3.取模数,我用过 $1e9+7$,$998244353$,用$2^{64}$也可以,这里利用自然溢出,一般不会有问题。提一句,$unsigned\space long\space long$做减法,即使算出来应该是负数,会自动加上$2^{64}$,相当于$(a+mod-b)%mod$了。没有问题。 处理hash: 1.预处理$K^{len}$

HashMap在Java1.7与1.8中的区别

风流意气都作罢 提交于 2020-04-06 00:24:23
基于 JDK1.7.0_80 与 JDK1.8.0_66 做的分析 JDK1.7中 使用一个Entry数组来存储数据,用key的hashcode取模来决定key会被放到数组里的位置,如果hashcode相同,或者hashcode取模后的结果相同(hash collision),那么这些key会被定位到Entry数组的同一个格子里,这些key会形成一个链表。 在hashcode特别差的情况下,比方说所有key的hashcode都相同,这个链表可能会很长,那么put/get操作都可能需要遍历这个链表 也就是说时间复杂度在最差情况下会退化到O(n) JDK1.8中 使用一个Node数组来存储数据,但这个Node可能是链表结构,也可能是红黑树结构 如果插入的key的hashcode相同,那么这些key也会被定位到Node数组的同一个格子里。 如果同一个格子里的key不超过8个,使用链表结构存储。 如果超过了8个,那么会调用treeifyBin函数,将链表转换为红黑树。 那么即使hashcode完全相同,由于红黑树的特点,查找某个特定元素,也只需要O(log n)的开销 也就是说put/get的操作的时间复杂度最差只有O(log n) 听起来挺不错,但是真正想要利用JDK1.8的好处,有一个限制: key的对象,必须 正确的实现了Compare接口 如果没有实现Compare接口

一致性Hash算法原理白话

拥有回忆 提交于 2020-04-05 23:18:05
1、技术背景 1.1、技术举例:Memcache 1.2、技术瓶颈 memcached服务器端本身不提供分布式cache的一致性,由客户端实现提供。以余数分布式算法为例。 余数分布式算法是根据添加进入缓存时key的hash值通过特定的算法得出余数,然后根据余数映射到关联的缓存服务器,将该key-value数据保存到该服务器 1.2.1、假设有3台缓存服务器以及它们对应的余数值 Node A:0,3,6,9 Node B:1,4,7 Node C:2,5,8 1.2.2、此时添加一台服务器Node D 服务器对应的余数值发生变化,如下 Node A:0,1,2 Node B:3,4 Node C:5,6 Node C:7,8,9 根据上面的变化,发现只有余数值为0,4,5所对应的缓存服务器没有发生改变,也就是说其它余数值对应的缓存服务器发生了改变,即缓存失效,如果大量缓存失效会严重影响系统的性能,也就是缓存动荡。针对这样大片缓存失效的技术瓶颈,于是提出了一致性hash算法。缩小失效缓存范围。 2、一致性Hash算法 2.1、将hash值范围看成一个0~2 32 的圆。 2.2、将服务器节点的hash值映射到该圆上。 2.3、对数据进行缓存时,计算key的hash值,然后找到该值在圆上的位置,顺时针进行查找,将数据保存到第一个查找到的服务器。 2.4、添加一个缓存服务器,如图

Hash一致性算法底层原理

浪子不回头ぞ 提交于 2020-04-05 23:17:27
大纲 Hash取余算法 判定哈希算法好坏的四个定义 一致性Hash算法的两大设计 Hash取余算法 hash( Object.key) %N,hash值随Object.key、N的变化而变化。 如果有节点(集群中节点增减太正常)发生变化,几乎重新分配,意味着所有已经分配好的数据都要迁移到新的节点上。 一致性Hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义 : 1、平衡性(Balance):平衡性是指哈希的结果能够尽可能分布在所有的缓冲(Cache)中去,这样可以使得所有的缓冲空间得到利用。很多哈希算法都能够满足这一条件。 2、单调性(Monotonicity):单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应该能够保证原有已分配的内容可以被映射到原有的或者新的缓冲中去,而不会映射到旧的缓冲集合中的其他缓冲区。 3、分散性(Spread):在分布式环境中,终端有可能看不到所有的缓冲,而只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上去,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度

Python学习之路--内置函数

岁酱吖の 提交于 2020-04-04 02:03:35
作用域相关 locals()、globals()# print(locals())# 返回本地作用域中的所有名字# print(globals()) #返回全局作用域中的所有名字# 迭代器.__next__()#next(迭代器)# 迭代器 = iter(可迭代的)# 迭代器 = 可迭代的.__iter__()# print('__next__' in dir(range(1,11,2)))# dir 查看一个变量拥有的方法# print(dir([]))#调用相关callable#变量 查看 callable()是否是个函数# print(callable(print))# a = 1# print(callable(a))# help 查看方法及其用法# help(str)#模块相关#import time# t = __import__('time')# print(t.time())#方法属于数据类型的变量,就用调用#如果某个方法不依赖于任何数据类型,就直接调用 -- 内置函数 和 自定义函数# 文件操作相关open()# f = open('file.py')# print(f.writable())# print(f.readable())# 内存相关 id()hash()# print(hash(123))# print(hash('dsf'))# print

Redis基本原理

人盡茶涼 提交于 2020-04-03 10:33:48
1、redis数据备份原理,RDB和AOF。 RDB:redis基于当前自身的所有数据所生成的数据快照,纯粹的数据,若redis从rdb启动,可直接加载使用。 AOF:类似redis日志文件,aof文件内部是redis收到的写命令,若redis从aof启动,需要先读aof文件,然后执行里面的命令,生产数据。 当触发生成rdb时,redis会开启后台线程,生成一份rdb,触发条件可以设置,类似隔多长时间或有多少数据改动时,生成rdb。 aof类似redis日志,可控制写入的频率,如每秒写入,当开启aof时(默认关闭),redis内部维护一个aof文件,实时将redis收到的写命令写入aof中。 aof由于不断地写入,会变得越来越大,当aof大小从0增大到设定的大小时,会触发aof的第一次rewrite操作,redis会将基于当前的数据生成新的aof文件,在此期间,如果redis收到新的写命令,redis会将写命令暂时保存在内存,等新的aof完成后,再将内存中的命令追加到新aof中,当新aof完全完成后(假设大小为n),redis会删除原aof文件。当新的aof文件不断扩大到2n时(默认2倍),会触发rewrite操作。 2、redis主从复制原理,断点续传和过期key处理 主从复制:redis主节点(master)向从节点(slave)复制数据,当集群没有任何问题正常运转时