分布式一致性之NWR策略模型

分布式一致性之NWR策略模型:
    <1>nwr策略解释:
    N:在分布式存储系统中,有多少份备份数据。
    W:代表一次成功的更新操作要求至少有w份数据写入成功 。
    R:代表一次成功的读数据操作要求至少有R份数据成功读取。

    <2>策略原理:    
        NWR值的不同组合会产生不同的一致性效果,当W+R>N的时候,整个系统对于客户端来讲能保证
    <3>不同组合产生的效果
        w+r > n  -> 对于客户端来说,强一致性保证。

  
        w+r <= n -> 因客户端读or写的时候,(再多线程情况下会导致数据非强一致性)

 

 

模拟代码:

package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"sync"
	"time"

	"github.com/bradfitz/gomemcache/memcache"
)

var mcDB []*memcache.Client
var (
	server1 = "host1:11211"
	server2 = "host2:11211"
	server3 = "host3:11211"
)

var wirte, read []string
var lock sync.RWMutex

func main() {
	// create a handle
	mc1 := memcache.New(server1)
	if mc1 == nil {
		fmt.Println("memcache1 New failed")
	}
	mc2 := memcache.New(server2)
	if mc2 == nil {
		fmt.Println("memcache2 New failed")
	}
	mc3 := memcache.New(server3)
	if mc3 == nil {
		fmt.Println("memcache3 New failed")
	}
	mcDB = append(mcDB, mc1)
	mcDB = append(mcDB, mc2)
	mcDB = append(mcDB, mc3)

	// 创建才是三个协程读取数据,三个协程序写数据
	var wg sync.WaitGroup
	go func() {
		wg.Add(1)
		defer wg.Done()
		//
		for {
			n := rand.Int() % 10
			key := "one_" + strconv.Itoa(n)
			// v := rand.Int() % 3 // 随机选取写入那个mc
			cnt := 0
			err := mcDB[0].Set(&memcache.Item{Key: key, Value: []byte(key)})
			if err == nil {
				cnt++
			}
			err = mcDB[1].Set(&memcache.Item{Key: key, Value: []byte(key)})
			if err == nil {
				cnt++
			}
			err = mcDB[2].Set(&memcache.Item{Key: key, Value: []byte(key)})
			if err == nil {
				cnt++
			}
			if cnt < 2 {
				// 少于2节点写入,认为写入失败,清理掉
				mcDB[0].Delete(key)
				mcDB[1].Delete(key)
				mcDB[2].Delete(key)
			} else {
				// 写入成功,展示俩表中标记
				lock.Lock()
				wirte = append(wirte, "v")
				lock.Unlock()
			}
			time.Sleep(time.Second * 1)
		}
	}()

	// read
	go func() {
		wg.Add(1)
		defer wg.Done()
		for {
			n := rand.Int() % 10
			key := "one_" + strconv.Itoa(n)
			cnt := 0
			if _, err := mcDB[0].Get(key); err == nil {
				cnt++
			}
			if _, err := mcDB[1].Get(key); err == nil {
				cnt++
			}
			if _, err := mcDB[2].Get(key); err == nil {
				cnt++
			}

			if cnt >= 2 {
				lock.Lock()
				read = append(read, "v")
				lock.Unlock()
			}
			time.Sleep(time.Second * 1)

		}
	}()
	// 独立一个协程输出当前list的内容
	go func() {
		for {
			lock.Lock()
			for _, v := range wirte {
				fmt.Print(v, "<w>")
			}
			fmt.Println()
			wirte = []string{}

			for _, v := range read {
				fmt.Print(v, "<r>")
			}
			fmt.Println()
			read = []string{}
			lock.Unlock()
			time.Sleep(time.Second * 3)
		}
	}()

	// 启动一个协程等待所有协程运行完成
	go func() {
		wg.Add(1)
		defer wg.Wait()
	}()

	// 主协助空跑,让所有子协程序跑起来
	fmt.Println("main is running ... ")
	select {}
}


结果:
v<w>v<w>v<w>
v<r>v<r>v<r>
v<w>v<w>v<w>
v<r>v<r>v<r>
v<w>v<w>
v<r>v<r>
v<w>v<w>v<w>
v<r>v<r>v<r>
v<w>v<w>
v<r>v<r>
v<w>v<w>v<w>
v<r>v<r>v<r>
v<w>v<w>v<w>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值