Maison >développement back-end >Golang >Comment les clés du KV Store sont-elles verrouillées ?
L'éditeur php Zimo vous révélera le secret du verrouillage par clé dans KV Store. Dans KV Store, le verrouillage des clés est réalisé grâce à une série d'algorithmes et de technologies complexes. Tout d'abord, le système génère un identifiant unique pour chaque clé et le stocke avec la valeur correspondante dans la base de données. Dans le même temps, le système utilisera également une fonction de hachage pour chiffrer la clé afin d'assurer sa sécurité. De plus, le système utilise également des listes de contrôle d'accès (ACL) pour restreindre l'accès aux clés afin que seuls les utilisateurs autorisés puissent effectuer des opérations de lecture et d'écriture. Grâce à ces mesures de sécurité, KV Store garantit la sécurité et la fiabilité des clés et fournit aux utilisateurs des services de stockage de données sûrs et fiables.
Je construis un magasin kv distribué juste pour en savoir plus sur les systèmes distribués et la concurrence. La mise en œuvre du stockage kv que je construis est entièrement transactionnelle, avec un journal des transactions en mémoire. Pour simplifier les choses, le stockage est également entièrement en mémoire. L'API est publique get
、insert
、update
、remove
. Notez que tous les points de terminaison fonctionnent sur une seule clé, et non sur une plage de clés.
Je gère la concurrence via des verrous. Cependant, j'ai un verrou global qui verrouille l'intégralité du magasin de données. Cela semble très inefficace, car si je veux mettre à jour la valeur de k2
时读取 k1
, je dois attendre que k2 termine la mise à jour, même si cela n'a pas d'importance.
Je sais que certaines bases de données utilisent un verrouillage plus fin. Par exemple, sur le serveur MySQL, il existe des verrous au niveau des lignes. Comment implémenter le verrouillage au niveau des clés ?
J'ai
type storage struct { store map[string]int32 }
Dois-je ajouter quelque chose comme ça ? :
type Storage struct { store map[string]int32 locks map[string]mutex.Lock }
Si je fais cela, le problème est que locks
必须与 store
保持同步。另一种选择是合并两个映射,但即便如此,如果 remove
请求出现在 get
avant, j'avais aussi le problème de supprimer les entrées dans la carte verrouillée.
Tout d’abord, une forte cohérence ne nécessite pas de journaux de transactions. Les journaux de transactions sont utiles pour conserver les propriétés acides.
Les transactions ne constituent pas non plus une exigence stricte pour une forte cohérence dans une base de données, mais elles peuvent être un outil utile pour garantir la cohérence dans de nombreuses situations.
Une cohérence forte fait référence à la propriété qui garantit que toutes les lectures de la base de données renverront l'écriture la plus récente, quel que soit l'endroit où l'opération de lecture est effectuée. En d’autres termes, une forte cohérence garantit que tous les clients verront les mêmes données et que les données seront à jour et cohérentes dans l’ensemble du système.
Vous pouvez utiliser des algorithmes de consensus tels que paxos ou raft pour garantir une forte cohérence. Lors du stockage de données, vous pouvez stocker une version des données et l'utiliser comme identifiant dans paxos.
Dans un magasin clé-valeur (kv), les clés sont généralement verrouillées à l'aide d'une sorte de mécanisme de verrouillage, tel qu'un mutex ou un verrou lecteur-écrivain (comme @paulsm4 l'a suggéré). Cela permet à plusieurs threads ou processus d'accéder et de modifier simultanément les données dans le magasin kv tout en garantissant que les données restent cohérentes et correctes.
Par exemple, lorsqu'un thread ou un processus souhaite lire ou modifier une clé spécifique dans le magasin kv, il peut acquérir un verrou sur cette clé. Cela empêche d'autres threads ou processus de modifier la même clé en même temps, provoquant des conditions de concurrence critique et d'autres problèmes. Une fois qu'un thread ou un processus a fini de lire ou de modifier la clé, le verrou peut être libéré, permettant à d'autres threads ou processus d'accéder à la clé.
Les détails spécifiques sur la façon de verrouiller les clés dans le stockage kv peuvent varier en fonction de la mise en œuvre du stockage kv. Certains magasins kv peuvent utiliser des verrous globaux (comme vous le faites déjà, ce qui est parfois inefficace) pour verrouiller l'intégralité du magasin de données, tandis que d'autres magasins kv peuvent utiliser des mécanismes de verrouillage plus fins tels que des verrous au niveau des lignes ou des verrous au niveau des clés pour permettre plus d'opérations. Accès simultané aux données.
Donc, tldr ; conceptuellement, vous avez raison. Le problème réside dans les détails d’implémentation du verrouillage.
Pour répondre strictement à votre question sur le verrouillage, pensez à Reader Lock comme @paulsm4 l'a suggéré. En Golang, un verrou similaire est rwmutex
rwmutex
。它用于 sync。 map
. Il est utilisé pour la sync. carte
.
Voici un court exemple :
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 }
En plus de cela, vous avez besoin de paxos pour assurer la cohérence entre les répliques.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!