2016-07-02 1 views
0

J'ai une application web plutôt complexe qui crée des pages HTML dans une base de données Cassandra.Pourquoi la modification du statut d'une page dans une base de données Cassandra ne fonctionne-t-elle pas toujours?

Lors de la création de la page, il enregistre un état dans cette page qui reflète le fait qu'il est en cours d'élaboration.

INSERT INTO content (key,     column1,   value) 
      VALUES ('http://domain/path', 'content:status', 0x0201); 

(Les noms de colonne proviennent de jours ... friperies)

Si le statut est 0x0201, aucun processus otherp ne peut rien faire à la page. Il est considéré comme étant verrouillé.

Une fois fait la création de la page, avec un ms ou, je changer le statut de « normal ». Ceci est un autre insert du champ content::status.

INSERT INTO content (key,     column1,   value) 
      VALUES ('http://domain/path', 'content:status', 0x0102); 

Voici les changements d'état de 0x0201 à 0x0102. Seulement, sur environ 700 pages que je crée lors de l'initialisation d'un site, ce statut ne change pas pour 22 à 30 d'entre eux (3% à 4%).

Cela peut-il se produire parce que le temps nécessaire entre le premier INSERT INTO et le second est trop court et le cluster Cassandra est confus? (ie voit les deux comme arrivant à peu près ensemble et il sélectionne l'un d'eux, il arrive juste d'être le mauvais dans ces quelques cas où il échoue?)

Répondre

0

En utilisant le pilote C++ (et d'autres je suis sûr) , les deux commandes INSERT peuvent finir par être envoyées à deux pipelines différents. Cela est dû au fait que le pilote gère les threads de travail et que les commandes peuvent aboutir dans l'un ou l'autre des pipelines de threads de travail. Cela signifie que même si vous envoyez CREATE et plus tard NORMAL, les pipelines de threads finiront par envoyer d'abord NORMAL puis CREATE à Cassandra (c'est-à-dire inverser l'ordre dans lequel les données ont été envoyées au pilote C++). avec un statut de CREATE ...

Cela ne peut pas être résolu directement. Au lieu de cela, vous souhaiterez peut-être utiliser un verrou tout en travaillant sur cette page, une fois le travail terminé, mettez également à jour l'état NORMAL au cas où il s'agirait d'autre chose, puis déverrouillez. Si vous avez un verrou avec un timeout, alors vous ne devriez jamais créer un interblocage complet (ie un processus gérant la page A puis B sans relâcher le verrou sur la page A avant de travailler sur B, un autre traitant d'abord la page B puis A ...

+0

Cela pourrait avoir à faire avec l'asymétrie de l'horloge sur les serveurs. Si ces mises à jour proviennent d'une instance de client unique, envisagez d'utiliser des horodatages côté client. Vous pouvez également envisager d'utiliser la coordination Compare-and-Set (transaction légère) pour garantir l'état attendu. –

+0

Oui. En fait, j'ai découvert que je pouvais ajouter 'USERING TIMESTAMP ms' à mes inserts ou demander au chauffeur de le faire avec un générateur. Cela ne change pas vraiment le fait que par défaut la commande n'est pas garantie ... –