2012-07-20 3 views
1

Je travaille sur un projet où j'utilise Riak avec Ripple, et j'ai trébuché sur un problème. Pour une raison quelconque, je reçois des doublons lors de la liaison de liens d'une structure de liens. Quand je longe la promenade en utilisant la boucle, je n'obtiens pas les doublons aussi loin que je peux voir.Duplicates lors de la liaison de riak à l'aide d'ondulations

La différence entre ma base boucle lien à pied

curl -v http://127.0.0.1:8098/riak/users/2306403e5177b4716da9df93b67300824aa2fd0e/_,projects,0/_,tasks,1 

et mon lien à base d'entraînement rubis/Riak client promenade

 result = Riak::MapReduce.new(self.robject.bucket.client). 
      add(self.robject.bucket,self.key). 
      link(Riak::WalkSpec.new({:key => 'projects'})). 
      link(Riak::WalkSpec.new({:key => 'tasks', :bucket=>'tasks'})). 
      map("function(v){ if(!JSON.parse(v.values[0].data).completed) {return [v];} else { return [];} }", {:keep => true}).run 

est aussi loin que je peux dire à la carte à la fin .

Cependant le résultat de la carte/réduire contient plusieurs doublons. Je ne peux pas comprendre pourquoi. Maintenant, je me suis contenté de supprimer les doublons en fonction de la clé, mais je souhaite que le résultat de riak ne contienne pas de doublons, car il semble inutile de supprimer les doublons à la fin.

J'ai essayé ce qui suit:

  • en vous assurant qu'il n'y a pas de doublons dans les liens ensembles de mes objets d'entraînement
  • Chargement des données sans la carte réduire, mais la promenade de lien contient les clés en double.

Toute aide est appréciée.

Répondre

2

Ce que vous rencontrez ici est un effet/challenge intéressant des requêtes Map/Reduce. Les requêtes M/R n'ont aucune notion de valeurs de quorum de lecture, et elles doivent nécessairement toucher chaque objet (dans les limites du filtrage d'entrée, bien sûr) sur chaque nœud. Ce qui signifie que lorsque N> 1, les requêtes doivent être frappées tous les copier de chaque objet.

Par exemple, disons N = 3, par défaut. Cela signifie que pour chaque objet écrit, il y a 3 copies, chacune sur 3 nœuds différents. Lorsque vous émettez une lecture pour un objet (disons avec la valeur de quorum par défaut R = 2), le nœud de coordination (qui a reçu la demande de lecture de votre client) contacte les 3 nœuds (et reçoit potentiellement 3 valeurs différentes, 3 différentes des copies de l'objet). Il vérifie ensuite qu'au moins deux de ces copies ont les mêmes valeurs (pour satisfaire à l'exigence R = 2), renvoie cette valeur convenue au client demandeur et rejette les autres copies. Ainsi, dans les opérations régulières (lectures/écritures, mais également la marche de liens), le nœud de coordination filtre les doublons pour vous.

Les requêtes Map/Reduce n'ont pas ce luxe. Ils n'ont pas vraiment de valeurs de quorum qui leur sont associées - ils sont faits pour itérer sur chaque clé et chaque objet (pertinent) sur tous les nœuds. Et parce que le code M/R s'exécute sur chaque nœud individuel (proche des données) au lieu de simplement sur le nœud de coordination, ils ne peuvent pas réellement filtrer les doublons intrinsèquement. Une des choses pour lesquelles ils ont été conçus, par exemple, est de mettre à jour (ou supprimer) toutes les copies des objets sur tous les nœuds. Ainsi, chaque phase de carte (dans votre cas ci-dessus) s'exécute sur chaque nœud, renvoie les valeurs «terminées» correspondantes pour chaque copie et renvoie les résultats au nœud de coordination pour revenir au client. Et comme il est très probable que votre N> 1, il y aura des doublons dans le jeu de résultats.Maintenant, vous pouvez probablement filtrer les doublons explicitement, en écrivant du code dans la phase Réduire, pour vérifier s'il y a déjà une clé présente et rejeter les doublons si c'est le cas, etc Mais honnêtement, si j'étais dans votre situation, Je voudrais juste filtrer les doublons dans ruby ​​du côté du client, plutôt que de jouer avec le code de réduction.

De toute façon, j'espère que cela éclairera un peu ce mystère.

+0

Réponse impressionnante! – Morten