Linux/C + + background development of common algorithms: consistent hashing algorithm __php

Source: Internet
Author: User
Tags md5 sprintf redis cluster

Consistent hashing is mainly used in large-scale high-availability distributed storage, especially for KV storage, such as memcaced, Redis cluster, compared to ordinary hash% N, but the advantage is that when adding or deleting nodes, the data migration will be relatively small, usually only partial jitter and migration. But its relative to the shortcomings of the hash%N data uniformity is certainly inferior to the hash%N especially the data key in a small range, easy to appear even phenomenon, but can be optimized by hash function, and increase the virtual node method to reduce the heterogeneity. Here is a C + + version of the consistent hash algorithm, where the M5 algorithm is the previous blog's Code

/********************************** function:consistent Hash Author:liuyi date:2015.10.31 viersion:1.0 ************* /#ifndef consistent_hash_h #define CONSISTENT_HASH_H #include <stdio.h> #include < string.h> #include <iostream> #include <set> #include <map> #include <string> #include <

vector> #include "md5.h" using namespace std;  
	inline unsigned int hash_fun (const char* key) {unsigned int hash = 0;  
	unsigned int seed = 131;  
	unsigned int len = strlen (key);
	for (int i = 0; i < len; i++) {hash = (hash * seed) + key[i];  
return hash;

typedef unsigned INT (*HASH_FUN_PTR) (const char*);
		Class Consistent_hash {Public:consistent_hash () {m_virtual_node_mulriple = 1;
		} ~consistent_hash () {m_node_map.clear (); BOOL Init (const vector<string>& node_vect, const int& virtual_node_mulriple, const HASH_FU

		n_ptr& hash_func = hash_fun); size_t gEt_virtual_node_hash (const string& node, vector<unsigned int>& Virtual_node_hash_vec);

		BOOL Add_node (const string& node);

		BOOL Del_node (const string& node);

		String Get_node (const string& key);

		size_t Get_all_node (set<string>& nodes);

	size_t Get_node_count ();
		Private:int m_virtual_node_mulriple;
		map<unsigned int, string> m_node_map;
Hash_fun_ptr M_hash_func;

}; 
 #endif


/********************************** function:consistent Hash Author:liuyi date:2015.10.31 viersion:1.0 ************* /#include "CONSISTENT_HASH.H" bool Consistent_hash::init (const vector<string>& Node_ Vect, const int& virtual_node_mulriple, const hash_fun_ptr& hash_func) {if (Node_vect.empty ()) RET

	Urn false;
	M_virtual_node_mulriple = Virtual_node_mulriple;
	M_hash_func = Hash_func;
		for (size_t i = 0; i < node_vect.size (); i++) {vector<unsigned int> Virtual_node_hash_vec;
		Get_virtual_node_hash (Node_vect[i], Virtual_node_hash_vec);
		for (size_t j = 0; J < Virtual_node_hash_vec.size (); j + +) {M_node_map[virtual_node_hash_vec[j]] = node_vect[i];
} return true; } size_t Consistent_hash::get_virtual_node_hash (const string& node, vector<unsigned int>& Virtual_node_
	Hash_vec) {virtual_node_hash_vec.clear ();
	Virtual_node_hash_vec.reserve (m_virtual_node_mulriple*4+1); for (int i = 0; i< M_virtual_node_mulriple;
		i++) {char virtual_node[256] = {0};
		sprintf (Virtual_node, "%s#%u", Node.c_str (), i);
		MD5 MD5;
		Md5.update (Virtual_node);
		Const unsigned char* digest = Md5.digest (); 
									  for (int h = 0; h < 4; h++) {unsigned int hash_value = ((unsigned int) (DIGEST[3+H*4]&AMP;0XFF) << 24) | ((unsigned int) (DIGEST[2+H*4]&AMP;0XFF) << 16) | ((unsigned int) (DIGEST[1+H*4]&AMP;0XFF) << 8) |

			(DIGEST[H*4]&AMP;0XFF);
		Virtual_node_hash_vec.push_back (Hash_value);
} return Virtual_node_hash_vec.size ();
	BOOL Consistent_hash::add_node (const string& node) {vector<unsigned int> Virtual_node_hash_vec;

	if (0 = get_virtual_node_hash (node, Virtual_node_hash_vec)) return false;
	for (size_t i = 0; i < virtual_node_hash_vec.size (); i++) {m_node_map[virtual_node_hash_vec[i]] = node;
return true; BOOL Consistent_hash::d el_node (const string& node) {vector<unsigned int> Virtual_nOde_hash_vec;

	if (0 = get_virtual_node_hash (node, Virtual_node_hash_vec)) return false;
	for (size_t i = 0; i < virtual_node_hash_vec.size (); i++) {m_node_map.erase (virtual_node_hash_vec[i));
return true;

	} string Consistent_hash::get_node (const string& key) {if (M_node_map.empty ()) return "";
	unsigned key_hash = M_hash_func (Key.c_str ());
	map<unsigned int, String>::iterator it = M_node_map.lower_bound (Key_hash);
	if (it = = M_node_map.end ()) {return m_node_map.begin ()->second;
Return it->second;
	} size_t Consistent_hash::get_all_node (set<string>& nodes) {nodes.clear (); 
		for (map<unsigned int, string>::iterator it = M_node_map.begin ();
		It!= m_node_map.end ();	
	++it) {Nodes.insert (It->second);
return Nodes.size ();
	} size_t Consistent_hash::get_node_count () {set<string> nodes;
return Get_all_node (nodes);
 }


#include <iostream>
#include "consistent_hash.h"

int main ()
{
	Consistent_hash C;
	Vector<string> A;
	A.push_back ("192.10.59.1:80");
	A.push_back ("192.10.59.2:80");
	A.push_back ("192.10.59.3:80");
	A.push_back ("192.10.59.4:80");
	A.push_back ("192.10.59.5:80");
	C.init (A, 1);
	set<string> nodes;
	Cout<<c.get_all_node (nodes) <<endl;
	Cout<<c.del_node ("192.10.59.1:80") <<endl;
	Cout<<c.get_all_node (nodes) <<endl;
	Cout<<c.add_node ("192.10.59.1:80") <<endl;
	Cout<<c.get_all_node (nodes) <<endl;
	for (int i = 0; i < 10000000 i++)
	{
		char b[1024] = {0};
		sprintf (b, "%d", I);
		string t = B;
		cout<< "node=" <<c.get_node (t) <<endl;
	}
}




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.