浅谈哈希函数和哈希表,布隆过滤器,一致性哈希

哈希的四种特征

  1. 输入可以无穷,输出是有穷尽的
  2. 输入相同的情况下,输出一定相同(不包含随机性)
  3. 不同的输入,有可能输出相同,此时的情况为哈希碰撞(概率极小)
  4. 均匀性和离散性能够得到保证
  5. 离散性或者均匀性越好,证明这个哈希函数越优秀。
  6. 哈希值%M:表示在0-M之间均匀分布。

哈希函数的题型

  1. 给40亿个数,然后给你1G内存,找出相同数值出现次数比较多的数。
  2. 40亿个数:约合为G为
    1. 16000000000 字节=14.9011612 G
  3. 按照传统的办法(暴力方法)用哈希表进行计算的话,最坏情况下40亿种不同的数据
    1. 远远超出题目所给的内存
  4. 解题思路:
    1. 利用哈希表进行分组
    2. 先对每个数进行哈希计算,得出一个哈希值:(x);再%100,14.9G往前推两位为0.149G,题目中说给的内存就够了。
    3. 相当于将数值进行了0-99的分组
      1. 对分组后的值再进行统计计算(此时用的是哈希表的累加),即使有哈希碰撞也进行累加。

传统的哈希表的实现套路

  1. 最关键的两部
    1. 构建哈希表
    2. 根据元素查找位置
  2. 构建哈希表相当于是一个计算hashcode值,然后是一个对号入座的关系,如果作为上有关系,用链表将其串起来,
    1. 当串联到一定程度就会进行扩容工作,保证哈希碰撞的减少
      1. 扩容类似于java的离线迁移,将数据一次性备份完毕后将旧的使用权迁移到新的,旧的使用权直接被垃圾回收。理论上也是一个O(1)的时间复杂度
  3. 查找的过程是一个计算出hashcode,然后根据地址进行检索,检索完毕后直接查找,不管是否有链表都是一个O(1)的关系,

关于哈希表的题

  1. 创建一种数据结构,要求实现下列方法

    1. insert:插入不能重复

    2. find:根绝key查找

    3. getRandom:返回一个随机的value

  2. 解题思路:

    1. 这里最难点是:如何将删除后数补上

      1. 概要一句话:

        1.  删除尾部,将尾部填充到被删除的那里。

布隆过滤器

  1. 应用的业务场景(解决是否存在的问题)
    1. 应在用redis的缓存穿透
    2. 应用在类似于黑名单的系统
  2. 在以前没有布隆过滤器的时候,如何做黑名单系统:hashMap/hashSet;但是如果黑名单有10亿个数据,放在内存就会有点不合适了,放在硬盘查询又会太慢。但是特点是:没有失误率~
  3. 布隆过滤器产生,他缩小空间的根本方法是使用是用的bit位的map,4个字节=32个bit,8个字节=64个bit。
  4. 布隆过滤器的构成三要素:
    1. 这个数据结构不可以删除
    2. 要确定样本量大小
    3. 要允许存在一定的四五率
  5. 根据这3个条件可以确定:
    1. hash函数的数量
    2. bit位map的大小
  6. 布隆过滤器的公式
    1. 计算布隆过滤器(有关布隆过滤器的题:1、又一定失误率。2、该数据结构可以进行修改。):
      1. bitmap计算公式:
        1. n为样本量,p为失误率
          1. 公式
        2. 哈希函数个数计算公式: m为bitmap的大小,n为样本量
          1. 公式
        3. 真实失误率 n:样本量,k:哈希函数个数,m:bitmap的大小
          1. 公式
      2. 总之bitmap太大,浪费空间,bitmap太小,失误率得不到保证。

一致性哈希

  1. 下面是来自百度百科:
    1. 一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。
      1.  在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题  。
  2. 服务分为逻辑服务和数据服务
    1. 逻辑服务的部署随便,因为逻辑相同,各个实例是等效的。
    2. 而数据层就不一样了
      1. 分布式的数据服务器存在底层如何维持的一个问题,
    3. 传统的数据分布式是如何存储:(用区别最大的键来左hash的key:例如:身份证号码,姓名,电话号码)。
      1. 将数据进行hashCode()方法后,然后%数据服务器的个数,将数据存储到对应的服务器中,因为hashCode的均匀性,会将数据均匀的存到各个数据库中
      2. 存在的问题:
        1. 如果服务器装载不下更多的数据的时候,此时需要对数据服务器进行扩容
        2. 扩容的代价比较大,需要对所有的数锯重新进行hashCode方法,然后再模与当前的数据库服务器,重新塞到数据服务器中。数据迁移的代价是全量的。
        3. 无法根据服务器的性能进行调节它所存储的
        4. 对于负载均衡问题无法进行处理。
          1. 负载问题是由该数据是否非常“红”来决定的
    4. 一致性哈希解决了经典的数据迁移的问题(代价降到最低)。
      1. 一致性hash里没有%这回事,但是依旧要进行hashCode的处理
      2. 做法:
        1. 用一个能将机器信息区分开的key来做hash,用机器的信息做hash值(此时用hash类的算法就行,我此处是MD5算法,因为值比较大,有更多的选择)
        2. 用信息做成环
          1. 步骤:
            1.  
          2. 当此时要多加一个数据库服务器或者减少一个数据库服务器的时候:
        3. 存在潜在的两个问题:
          1. 机器数量很少可能一上来不均分
          2. 增加一台机器或者减少一台机器,负载可能不均衡
        4. 解决上面的问题:用虚拟节点技术
          1. 每个机器随机均匀预设1000个虚拟节点,三个机器就是3000个虚拟节点
            1. 在环中,随机一块区域,每个节点的个数均匀,整个环中,节点个数均匀。
          2. 当增加机器的时候又多出1000个虚拟节点,总计4000个虚拟节点
            1. 新加的4号机器从123机器中各抽出等比例的节点,最终凑成自己的1/4。减少也是同理。
      3. 一致性哈希和虚拟节点搭配还可以管理负载,能者虚拟节点多点,弱者,虚拟节点少点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值