Maison  >  Article  >  développement back-end  >  Cartographie simultanée avec des tranches en golang

Cartographie simultanée avec des tranches en golang

WBOY
WBOYavant
2024-02-11 09:57:091097parcourir

golang 中带有切片的并发映射

L'éditeur php Banana a apporté un merveilleux article sur la cartographie simultanée des tranches dans Golang. Dans cet article, nous verrons comment utiliser les tranches pour les opérations de mappage dans un environnement simultané et expliquerons pourquoi les tranches sont très utiles dans la programmation simultanée. En utilisant le mécanisme de concurrence de Golang, nous pouvons accéder et modifier des tranches dans plusieurs goroutines en même temps, améliorant ainsi les performances et l'efficacité du programme. Que vous soyez débutant ou développeur Golang expérimenté, cet article vous apportera de précieuses connaissances et compétences pratiques. Explorons le mappage simultané avec des tranches dans Golang !

Contenu de la question

J'ai essayé de résoudre un problème de concurrence après le départ de l'un des développeurs du domaine il y a quelques mois, mais je ne trouve pas de moyen approprié de résoudre ce problème.

Pour le contexte, nous chargeons les données client dans une structure comme celle-ci :

[ 键 ] -> { 值 }

[客户特定哈希] -> {数据点/文件切片}

Exemple - formatage vraiment mauvais, désolé :

[a60d849ad97bfb833e1096941] 
-> 
{ 
 { StartDate: '01-02-2022', EndDate: '28-02-2022', DataFrames: [1598,921578,12981,21749,192578...]},
 { StartDate: '01-03-2022', EndDate: '28-03-2022', DataFrames: [1234,1567,6781,126978...]},
}

Ce qui précède est dû au fait que nous avons 100 000 clients et que chaque nuit nous lançons un processus pour consolider les données en fonction du hachage de chaque client (ou en fait d'un bucket). Avant de traiter les trames de données, nous parcourons les tranches et « fusionnons » les trames de données en une seule grande trame de données contenant de nombreuses règles juridiques/comptables.

Il s'exécute dans une goroutine pour indexer tous les points de données le plus rapidement possible.

Donc, l'implémentation est essentiellement un sync.Map[string, []DataFrame] Mais j'ai remarqué que même si l'opération de carte est protégée, l'ajout à la tranche de dataframe ne l'est pas. Chaque hachage contient probablement environ 20 à 30 références de fichiers dans cette tranche par nuit.

Il y a de fortes chances que les données clients aient été fusionnées de manière incorrecte au cours des deux dernières années et je suis chargé de corriger ce problème. Avant sync.map, ils utilisaient à nouveau RWMutex avec Map, mais pas le découpage, ce qui renvoie à cet article comme guide.

Tout d’abord, l’idée d’une Map contenant des tranches est-elle une structure de données appropriée ?

J'essaie de créer un gestionnaire de tranches basé sur RWMutex mais je me demandais si une Map pouvait en avoir un chan DataFrame 来代替在索引客户文件时放入,然后一旦完成,第二步将其合并到一个数组中(如len(chanx)) serait-il connu ?

Je viens principalement de Java, donc je pourrais être confondu avec certaines terminologies, donc je suis désolé.

Solution

Vous avez deux problèmes différents :

  1. Des problèmes de concurrence sont survenus lors de la mise à jour de la carte
  2. Problèmes de concurrence lors de la mise à jour des entrées de carte

sync.Map en empêchera 1, mais pas 2.

Une façon de résoudre ce problème est :

sync.Map[string, *DFrame]

type DFrame struct {
  sync.RWMutex 
  Data []DataFrame
}

Une fois que vous avez obtenu les entrées de la carte, vous devez LockRLock 它,然后使用数据。这不仅仅限于切片的附加。即使您只从数据帧中读取,您也必须 RLock la structure.

Donc, si vous souhaitez ajouter un nouveau dataframe :

df := &DFrame{}
entry,_:=m.LoadOrStore(key, df)
dfEntry:=entry.(*DFrame)
dfEntry.Lock()
dfEntry.Data=append(dfEntry.Data, newDataFrame)
dfEntry.Unlock()

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer