日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
突破Redis槽多實(shí)例帶來的一致性哈希困境(redis槽一致性哈希)

隨著Redis的應(yīng)用越來越廣泛,特別是在分布式系統(tǒng)的應(yīng)用中,很多用戶為了提高Redis的可用性和性能,通過多實(shí)例的方式來部署Redis。雖然多實(shí)例的部署方案在實(shí)現(xiàn)和部署上相對簡單,但也存在一系列問題,其中一個(gè)比較嚴(yán)重的問題就是Redis槽機(jī)制在多實(shí)例部署下可能會(huì)產(chǎn)生的一致性哈希困境。如何突破這個(gè)困境是當(dāng)前Redis多實(shí)例化部署必須解決的一個(gè)難題。

創(chuàng)新互聯(lián)建站主營鯉城網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,成都App制作,鯉城h5微信小程序開發(fā)搭建,鯉城網(wǎng)站營銷推廣歡迎鯉城等地區(qū)企業(yè)咨詢

#### 什么是Redis槽機(jī)制?

Redis槽機(jī)制是在Redis集群模式中采用的一種數(shù)據(jù)分片方式,其核心思想是將整個(gè)數(shù)據(jù)空間劃分為16384個(gè)槽位,然后將這些槽位均分到各個(gè)節(jié)點(diǎn)中去進(jìn)行存儲(chǔ)。具體地,每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分槽位,根據(jù)key進(jìn)行hash后得到的hash值對應(yīng)的槽位確定數(shù)據(jù)存儲(chǔ)在哪個(gè)節(jié)點(diǎn)中。這樣的實(shí)現(xiàn)方式簡單易用,同時(shí)也滿足了分布式場景下數(shù)據(jù)的可用性和可擴(kuò)展性。

#### Redis多實(shí)例部署存在的問題

在Redis集群中,各個(gè)節(jié)點(diǎn)通過互相通信以及槽位重定向機(jī)制來保持?jǐn)?shù)據(jù)的一致性。但是,在Redis多實(shí)例部署中,如果各個(gè)實(shí)例之間單獨(dú)運(yùn)行,那么就會(huì)出現(xiàn)各個(gè)實(shí)例之間數(shù)據(jù)不一致、數(shù)據(jù)重復(fù)、數(shù)據(jù)漏掉等問題,因?yàn)楦鱾€(gè)實(shí)例之間并沒有數(shù)據(jù)的交互和協(xié)同。為了解決這個(gè)問題,就有了采用一致性哈希的方式來保證數(shù)據(jù)的一致性。一致性哈希的核心就是通過key進(jìn)行hash后映射到不同的節(jié)點(diǎn)中去進(jìn)行存儲(chǔ),這樣就可以通過限定訪問某個(gè)實(shí)例的數(shù)據(jù)來減少不同實(shí)例之間的數(shù)據(jù)重復(fù)。但是,一致性哈希也存在一些問題,其中一個(gè)比較嚴(yán)重的問題就是哈希傾斜。也就是某個(gè)節(jié)點(diǎn)對應(yīng)的哈希值范圍過大,導(dǎo)致大量的數(shù)據(jù)都被存儲(chǔ)到該節(jié)點(diǎn)上,從而導(dǎo)致該節(jié)點(diǎn)的性能受到影響。

#### 如何突破一致性哈希困境?

為了突破哈希傾斜的問題,業(yè)界提出了兩種解決方案。一種是提出一些負(fù)載均衡策略,如Round-Robin、Least-Connection等,按照輪詢或者連接數(shù)的方式來均衡各個(gè)節(jié)點(diǎn)的負(fù)載。這種方法通常采用在Redis集群和代理中來實(shí)現(xiàn),但是由于其實(shí)現(xiàn)復(fù)雜度較高且性能有所損耗,也存在相應(yīng)的問題,比如單一節(jié)點(diǎn)故障的影響較大等問題。

另一種則是在一致性哈希的基礎(chǔ)上優(yōu)化,提出了一些虛擬節(jié)點(diǎn)的概念。具體地,為了使每個(gè)實(shí)例的負(fù)載均衡,我們可以將每個(gè)實(shí)例對應(yīng)一個(gè)或多個(gè)虛擬節(jié)點(diǎn),并將這些虛擬節(jié)點(diǎn)按照哈希值等間隔地分散在整個(gè)哈希環(huán)中,使得哈希環(huán)上的節(jié)點(diǎn)數(shù)大于實(shí)際節(jié)點(diǎn)數(shù),從而達(dá)到負(fù)載均衡的目的。這種方式能夠有效地解決哈希傾斜的問題,同時(shí)還能夠保持?jǐn)?shù)據(jù)分布的一致性。在Redis集群和代理中也可以實(shí)現(xiàn)這種方式,以保證集群和代理的負(fù)載均衡,進(jìn)而保證數(shù)據(jù)分布的平衡。

下面介紹一下RedisCluster中基于虛擬節(jié)點(diǎn)的一致性哈希的實(shí)現(xiàn)方式,代碼如下(以Python為例):

“`python

class VirtualNode(object):

def __init__(self, node, index):

# node: 真實(shí)的節(jié)點(diǎn)對象

# index: 虛擬節(jié)點(diǎn)索引號

self.node = node

self.index = index

self.vnode_key = “%s-vnode%s” % (node.ip, index)

self.hashcode = md5(self.vnode_key).hexdigest()

class VirtualNodeCluster(object):

def __init__(self, nodes, vnum=512):

# nodes: 真實(shí)的節(jié)點(diǎn)列表

# vnum: 每個(gè)真實(shí)節(jié)點(diǎn)對應(yīng)的虛擬節(jié)點(diǎn)數(shù)量

self.hcircle = {}

for node in nodes:

for i in range(vnum):

vnode = VirtualNode(node, i)

self.hcircle[vnode.hashcode] = vnode

def get_node(self, key):

# 虛擬環(huán)上的節(jié)點(diǎn)按哈希值排序

hkeys = sorted(self.hcircle.keys())

if not hkeys:

return None

# 獲取key的哈希值并定位在虛擬環(huán)上

key_hash = md5(key).hexdigest()

for hkey in hkeys:

if key_hash

vnode = self.hcircle[hkey]

return vnode.node

return self.hcircle[hkeys[0]].node


上述代碼通過VirtualNode和VirtualNodeCluster實(shí)現(xiàn)了一致性哈希算法。其中,VirtualNode表示虛擬節(jié)點(diǎn),包含真實(shí)節(jié)點(diǎn)、虛擬節(jié)點(diǎn)索引號、虛擬節(jié)點(diǎn)key以及虛擬節(jié)點(diǎn)哈希值等信息;VirtualNodeCluster則是一組虛擬節(jié)點(diǎn)的集合,通過對所有真實(shí)節(jié)點(diǎn)進(jìn)行哈希后,將其對應(yīng)的虛擬節(jié)點(diǎn)平均散布在哈希環(huán)中。在get_node函數(shù)中,則是具體的一致性哈希實(shí)現(xiàn)算法,通過key進(jìn)行哈希后沿著哈希環(huán)定位到下一個(gè)節(jié)點(diǎn),最終返回對應(yīng)的真實(shí)節(jié)點(diǎn)。

再來看一下使用上述代碼實(shí)現(xiàn)Redis多實(shí)例化部署一致哈希的方式,如下:

```python
import redis
class MyRedis(object):
def __init__(self, nodes, vnum=512, type='sentinel', master=None, name=None):
if type == 'sentinel':
self.conn = redis.RedisSentinel(nodes, socket_timeout=5)
self.connect = self.conn.master_for(master, socket_timeout=5)
elif type == 'cluster':
self.cluster = rediscluster.RedisCluster(startup_nodes=nodes)
else:
rse ValueError('invalid type: %s' % type)

# 新增如下代碼
self.cluster_nodes = [{'ip': node['ip'], 'port': node['port']} for node in nodes]
self.cluster_vnode = VirtualNodeCluster(self.cluster_nodes, vnum)

def __getattr__(self, name):
# 新增如下代碼
if name in ['get', 'set']:
return self._hash_value(name)
if hasattr(self.conn, name):
return getattr(self.conn, name)
rse AttributeError(name)

# 新增如下代碼
def _hash_value(self, name):
def _wrapper(key, *args, **kwargs):
node = self.cluster_node.get_node(key)
client = redis.Redis(host=node['ip'], port=node['port'], socket_timeout=5)
func = getattr(client, name)
return func(key, *args, **kwargs)
return _wrapper

在MyRedis中,我們支持sentinel和cluster兩種Redis多實(shí)例化部署方式,并新增_cluster_nodes和_cluster_vnode兩個(gè)屬性,其中_cluster_nodes存儲(chǔ)所有節(jié)點(diǎn)的ip和port信息,_cluster_vnode存儲(chǔ)了所有節(jié)點(diǎn)對應(yīng)的虛擬節(jié)點(diǎn)。在__getattr__函數(shù)中,我們對get和set等常用的方法進(jìn)行了擴(kuò)展,通過自定義的_wrapper函數(shù),調(diào)用一致性哈希算法獲取對應(yīng)的節(jié)點(diǎn),再使用對應(yīng)的client對象來對數(shù)據(jù)進(jìn)行g(shù)et和

成都網(wǎng)站推廣找創(chuàng)新互聯(lián),老牌網(wǎng)站營銷公司
成都網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)(www.cdcxhl.com)專注高端網(wǎng)站建設(shè),網(wǎng)頁設(shè)計(jì)制作,網(wǎng)站維護(hù),網(wǎng)絡(luò)營銷,SEO優(yōu)化推廣,快速提升企業(yè)網(wǎng)站排名等一站式服務(wù)。IDC基礎(chǔ)服務(wù):云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn)、服務(wù)器租用、服務(wù)器托管提供四川、成都、綿陽、雅安、重慶、貴州、昆明、鄭州、湖北十堰機(jī)房互聯(lián)網(wǎng)數(shù)據(jù)中心業(yè)務(wù)。


分享文章:突破Redis槽多實(shí)例帶來的一致性哈希困境(redis槽一致性哈希)
當(dāng)前網(wǎng)址:http://www.dlmjj.cn/article/djehogh.html