首頁 >後端開發 >Golang >KV Store 中的金鑰是如何鎖定的?

KV Store 中的金鑰是如何鎖定的?

WBOY
WBOY轉載
2024-02-09 13:20:09957瀏覽

KV Store 中的密钥是如何锁定的?

php小編子墨將為您揭開KV Store中密鑰鎖定的奧秘。在KV Store中,金鑰的鎖定是透過一系列複雜的演算法和技術實現的。首先,系統會為每個密鑰產生一個唯一的標識符,並將其與對應的值儲存在資料庫中。同時,系統也會採用雜湊函數對金鑰進行加密,確保其安全性。此外,系統也會使用存取控制清單(ACL)來限制對金鑰的存取權限,只有授權的使用者才能進行讀寫操作。透過這些安全措施,KV Store保證了金鑰的安全性和可靠性,為用戶提供了安全可靠的資料儲存服務。

問題內容

我正在建立一個分散式 kv 存儲,只是為了更多地了解分散式系統和並發性。我正在建立的 kv 儲存的實作是完全事務性的,具有記憶體中事務日誌。為了簡單起見,儲存也完全位於記憶體中。該 api 公開 getinsertupdateremove。請注意,所有端點都在單一鍵上運行,而不是在一系列鍵上運行。

我透過鎖定管理並發。但是,我有一個全域鎖來鎖定整個資料儲存。這聽起來效率非常低,因為如果我想在更新 k2 時讀取 k1 的值,我必須等待 k2 完成更新,儘管不相關。

我知道有些資料庫使用更細緻的鎖定。例如,在 mysql 伺服器中存在行級鎖定。鍵級鎖如何實現?

我有

type storage struct {
  store map[string]int32
}

我應該要加這樣的東西嗎? :

type Storage struct {
  store map[string]int32
  locks map[string]mutex.Lock
}

如果我這樣做,問題是 locks 必須與 store 保持同步。另一個選擇是合併兩個映射,但即便如此,如果remove 請求出現在get 之前,我也會遇到在鎖定時刪除映射中的條目的問題。

解決方法

概念部分

交易

首先,強一致性不需要交易日誌。交易日誌對於維護 acid 屬性非常有用。

事務也不是資料庫中強一致性的嚴格要求,但它們可以成為在許多情況下確保一致性的有用工具。

強一致性是指確保資料庫的所有讀取都會傳回最近的寫入的屬性,無論讀取操作在何處執行。換句話說,強一致性保證所有客戶端都會看到相同的數據,並且數據在整個系統中都是最新的和一致的。

您可以使用paxos或raft等共識演算法來保證強一致性。儲存資料時,資料可以儲存一個版本,並將其作為paxos中的id。

鎖定 kv 儲存

在鍵值(kv)儲存中,鍵通常使用某種鎖定機制來鎖定,例如互斥鎖或讀寫器鎖(如@paulsm4所建議)。這允許多個執行緒或進程同時存取和修改 kv 儲存中的數據,同時仍確保資料保持一致和正確。

例如,當執行緒或程序想要讀取或修改 kv 儲存中的特定鍵時,它可以取得該鍵的鎖。這可以防止其他執行緒或進程同時修改相同鍵,從而導致競爭條件和其他問題。一旦執行緒或程序完成讀取或修改金鑰,就可以釋放鎖,允許其他執行緒或程序存取該金鑰。

如何在 kv 儲存中鎖定金鑰的具體細節可能會有所不同,具體取決於 kv 儲存的實作。一些kv 存儲可能會使用全域鎖(正如您已經在做的那樣,這有時效率很低)來鎖定整個資料存儲,而其他kv 存儲可能會使用更細粒度的鎖定機制,例如行級鎖或鍵級鎖,以允許更多的操作。並發存取資料。

所以,tldr;從概念上講,你是對的。問題在於鎖定的實作細節。

編碼

要嚴格回答有關鎖定的問題,可以考慮讀寫器鎖定 正如@paulsm4 所建議的。在golang中,類似的鎖是 rwmutex。它用於 sync。 map.

這是一個簡短的範例:

type Storage struct {
  store sync.Map // a concurrent map
}

// GET retrieves the value for the given key.
func (s *Storage) GET(key string) (int32, error) {
  // Acquire a read lock for the key.
  v, ok := s.store.Load(key)
  if !ok {
    return 0, fmt.Errorf("key not found: %s", key)
  }

  // Return the value.
  return v.(int32), nil
}

// INSERT inserts the given key-value pair into the data store.
func (s *Storage) INSERT(key string, value int32) error {
  // Acquire a write lock for the key.
  s.store.Store(key, value)
  return nil
}

// UPDATE updates the value for the given key.
func (s *Storage) UPDATE(key string, value int32) error {
  // Acquire a write lock for the key.
  s.store.Store(key, value)
  return nil
}

// REMOVE removes the key-value pair for the given key from the data store.
func (s *Storage) REMOVE(key string) error {
  // Acquire a write lock for the key.
  s.store.Delete(key)
  return nil
}

除此之外,您還需要 paxos 以確保副本之間的一致性。

以上是KV Store 中的金鑰是如何鎖定的?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除