哈希环算法(C语言版本)

文章目录

理论分析:

所谓的哈希环就是就是数据结构里面的数组,只不过我们通过设置使其首尾相连,而这个数组又非常的大,这些大量的元素空间就可以用于存放我们的哈希映射点。在haproxy当中,该算法进行哈希的时候是以IP地址进行哈希,并不是以权值进行哈希,请勿绕晕。

经典案例

案例一:开放寻址法

链接如下:
https://blog.csdn.net/qq_64304610/article/details/141063561?spm=1001.2014.3001.5501

开放寻址法的大致思想回合哈希环的思想一致,只不过开发寻址法的算法题目没有要求首尾相连,但是其思路简单,易于理解。

案例二:经典哈希环算法案例

题目名称:基于哈希环的数据分布与负载均衡

题目描述:

假设你正在为一家在线零售商设计一个分布式缓存系统,该系统需要处理大量的商品查询请求。为了提高查询效率和系统的可扩展性,你决定使用哈希环算法来分布数据和负载均衡。系统中有多个缓存节点,每个节点负责存储一部分商品数据。当客户端发起商品查询请求时,系统需要根据商品ID将请求路由到对应的缓存节点。

要求: 设计一个简单的哈希函数,将商品ID映射到哈希环上。 实现一个负载均衡器,根据哈希环上的位置选择合适的缓存节点来处理请求。

考虑节点的添加和删除情况,确保系统的容错性和可扩展性。 输入:

商品ID列表 缓存节点列表 客户端查询请求(包含商品ID)

输出: 每次查询请求对应的缓存节点编号

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

// 定义哈希环的大小,这里定义了哈希环的大小为2的20次方,即哈希环的范围是从0到2^20-1。
int RING_SIZE=(1<<20); 


// 定义缓存节点结构体
typedef struct {
    int id; //id表示缓存节点的唯一标识
    unsigned int hash; //hash表示该节点在哈希环上的位置。
} CacheNode; //定义了一个名为CacheNode的结构体

// 简单哈希函数
unsigned int simple_hash(const char *str) {
    unsigned int hash = 0;
    while (*str) {
        hash = hash * 31 + *str++;
    }
    return hash % RING_SIZE;
}/*
  这是一个简单的字符串哈希函数,它使用了一个基本的乘法散列策略。
  对于输入的字符串,它会遍历每个字符,
  并将字符的ASCII值乘以31后累加到hash变量上。
  最后,对哈希值取模RING_SIZE,确保哈希值落在哈希环的有效范围内。
*/

// 初始化缓存节点
void init_cache_node(CacheNode *node, int id, const char *data) {
    node->id = id;
    node->hash = simple_hash(data);
}
/*
这个函数用于初始化一个CacheNode结构体。
它接受一个指向CacheNode的指针、一个节点ID和一个数据字符串作为参数。
函数设置节点的ID,并计算数据字符串的哈希值,将其赋给节点的hash成员。
*/

// 查找最近的缓存节点
/*
这个函数用于在哈希环上查找距离给定键哈希值最近的缓存节点。
它遍历所有缓存节点,找到第一个哈希值大于或等于键哈希值的节点,
并返回其ID。如果没有找到这样的节点,则返回第一个节点的ID。
*/
int find_nearest_node(CacheNode *nodes, int num_nodes, unsigned int key_hash) {
    int nearest_node = -1;
    for (int i = 0; i < num_nodes; ++i) {
        if (nodes[i].hash >= key_hash) {
            nearest_node = nodes[i].id;
            break;
        }
    }
    if (nearest_node == -1) {
        // 如果哈希环上没有找到比key_hash大的节点,则返回第一个节点
        nearest_node = nodes[0].id;
    }
    return nearest_node;
}

int main() {
    // 假设有3个缓存节点
    CacheNode nodes[3];
    init_cache_node(&nodes[0], 0, "node0");
    init_cache_node(&nodes[1], 1, "node1");
    init_cache_node(&nodes[2], 2, "node2");

    // 商品ID列表
    const char *product_ids[] = {"product1", "product2", "product3"};

    // 客户端查询请求
    const char *query_id = "product2";

    // 计算查询请求的哈希值
    unsigned int query_hash = simple_hash(query_id);

    // 查找最近的缓存节点
    int nearest_node = find_nearest_node(nodes, 3, query_hash);

    printf("产品"%s"的查询应由%d缓存节点处理 \n", query_id, nearest_node);

    return 0;
}
总结

这段代码定义了一个简单的哈希函数simple_hash,用于将商品ID映射到哈希环上。init_cache_node函数用于初始化缓存节点,find_nearest_node函数用于根据哈希值查找最近的缓存节点。在main函数中,我们模拟了3个缓存节点和一个商品查询请求,并演示了如何使用哈希环算法来路由请求。

相关推荐
woshilys33 分钟前
sql server 查询对象的修改时间
运维·数据库·sqlserver
疯狂飙车的蜗牛1 小时前
从零玩转CanMV-K230(4)-小核Linux驱动开发参考
linux·运维·驱动开发
恩爸编程2 小时前
探索 Nginx:Web 世界的幕后英雄
运维·nginx·nginx反向代理·nginx是什么·nginx静态资源服务器·nginx服务器·nginx解决哪些问题
Michaelwubo3 小时前
Docker dockerfile镜像编码 centos7
运维·docker·容器
XH华3 小时前
初识C语言之二维数组(下)
c语言·算法
好像是个likun4 小时前
使用docker拉取镜像很慢或者总是超时的问题
运维·docker·容器
南宫生4 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
不想当程序猿_4 小时前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
落魄君子4 小时前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘
菜鸡中的奋斗鸡→挣扎鸡4 小时前
滑动窗口 + 算法复习
数据结构·算法