记录解决HashMap与HashPartition中数据量过大发生Hash冲突问题

8 篇文章 0 订阅

1. 背景

在一次实现Spark需求时,需要实现repartitionAndSortWithinPartitions算子,具体代码见: 浅谈 repartitionAndSortWithinPartitions
这里需要先对数据进行分区, 刚开始使用的方法是直接对字符串进行hashCode,hashCode处
但是后来使用这个算子实现的功能并不能满足PM的需求,就开始查BUG

2. 查找问题

HashPartitioner分区冲突

刚开始问题定位到了hashCode冲突上,因为需要hash的字符串(暂且叫logid)很长,且有许多特殊字符.查到当有特殊字符且字母分大小写时,hash冲突率很高.
此处直接将.hashcode改为了纯数字md5方式.这里直接贴一个scala版本纯数字md5的方法供大家参考.

  def getMD5(str: String): Long = {
    val id_map = Map("a" -> "1", "b" -> "2", "c" -> "3", "d" -> "4", "e" -> "5", "f" -> "6", "g" -> "7")
    // 第一步,获取MessageDigest对象,参数为MD5表示这是一个MD5算法
    val md5 = MessageDigest.getInstance("MD5")
    //md5.update("aayz".getBytes("UTF-8"))
    val array = md5.digest(str.getBytes("UTF-8"))
    val bigInt = new BigInteger(1, array).toString(16).substring(8, 24) // resultStr
    var strm = ""
    for (i <- bigInt) {
      if (id_map.contains(i.toString)) strm += id_map(i.toString) else strm += i
    }
    strm.toLong
  }

hashMap中hash冲突

将hashcode修改为md5后发现需求还未达到要求, 就继续查找问题. 发现在此处使用到了HashMap,每个partition中数据量过大,同样会出现Hash冲突的问题.
HashMap量过大发生Hash冲突
将HashMap中的key进行md5,然后重新塞入

3. 总结

当HashMap的Key是较长的字符串且数据量较大时,极容易出现Hash冲突,此时建议将Key做进一步处理, 如MD5后再塞回,可降低Hash冲突率,减少Hash重复的数量

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值