Cassandra - choix du datacenter local

Lorsqu’on déploie Cassandra sur plusieurs datacenters, on souhaite généralement que les clients se connectent aux nœuds d’un datacenter en particulier. En effet, selon les motivations pour lesquelles on déploie un cluster sur plusieurs datacenters, on voudra soit privilégier le trafic local, soit isoler la charge créée par un traitement donné sur un datacenter particulier. Mais comment le Driver Cassandra sait-il sur quel datacenter il doit travailler alors que je ne lui ai rien dit ?

Une des raisons pour lesquelles Cassandra est facile à faire fonctionner sont les comportements automagiques tel que le choix du datacenter local. Cependant, pour maitriser l’outil et se prémunir des mauvaises surprises, il est sain de se poser quelques questions :

  • Comment le driver sait-il sur quel datacenter il doit se connecter ?
  • Peut-il se tromper ?
  • Comment lui indiquer le bon datacenter ?

LoadBalancingPolicy

Le choix d’un nœud pour envoyer une requête est délégué à un composant particulier nommé LoadBalancingPolicy. Ce composant est fourni lors de la création de l’objet Cluster. Par défaut, le driver utilise une chaîne de deux politiques : TokenAwarePolicy et DCAwareRoundRobinPolicy. La première restreint les nœuds sélectionnés pour jouer le rôle de coordinateur aux noeuds qui possèdent la donnée. Il permet ainsi de réduire le nombre de bonds sur le réseau. Il délègue le choix initial des nœuds disponibles à une autre politique ; ici DCAwareRoundRobinPolicy qui sélectionne les nœuds présents sur le même datacenter que le client.

Pour une utilisation classique, ce choix par défaut est le meilleur parmi les politiques fournies avec le driver. Il est possible d’en choisir une autre comme DCAwareFailoverRoundRobinPolicy écrit par Alexander Dejanovski (https://github.com/adejanovski/cassandra-dcaware-failover). Ce dernier ajoute un mécanisme de bascule vers un autre datacenter des requêtes de niveau de cohérence LOCAL_* qui ne sont pas routées ailleurs en cas de défaillance locale. Mais on reste souvent sur le choix par défaut.

Détection du client

Pour fonctionner, le DCAwareRoundRobinPolicy a besoin de savoir sur quel datacenter se situe le client. Pour cela, il y a deux méthodes :

  1. on le lui dit explicitement,
  2. il le détecte automatiquement.

C’est souvent le deuxième, plus simple, qui est employé.

La sélection fonctionne assez bien grâce à l’algorithme suivant :

  1. Si le DC est fourni dans la configuration, cette valeur est choisie et le driver écrira la ligne suivante dans le journal d’exécution : INFO Using provided data-center name 'dc-nantes' for DCAwareRoundRobinPolicy
  2. Sinon, il est défini à partir d’un des nœuds de l’ensemble des points de contact (des nœuds Cassandra) fournis dans la configuration. À cause de l’implémentation qui utilise un HashSet, ce nœud peut être n’importe lequel dans l’ensemble. Le driver informera de son choix dans le journal d’exécution : INFO Using data-center name 'dc-nantes' for DCAwareRoundRobinPolicy (if this is incorrect, please provide the correct datacenter name with DCAwareRoundRobinPolicy constructor)
  3. Ensuite, il vérifiera que tous les autres nœuds de l’ensemble des points de contact sont rattachés au même DC.
  4. Si ce n’est pas le cas, un avertissement est écrit dans le journal d’exécution : WARN Some contact points don't match local data center. Local DC = dc-bordeaux. Non-conforming contact points: cass-paris-04,cass-paris-09​
  5. Par contre, il ne reviendra pas sur ​son choix. Il est donc souhaitable de surveiller l’apparition de ce genre de ligne dans les logs de l’application cliente, car un tel paramétrage relève du tirage au sort.

Pour spécifier le datacenter local, il faut le passer en paramètre lors de la construction de la politique de répartition lors de la connexion au clusteur :

Cluster.Builder builder = Cluster.builder() .addContactPoint(host1) .addContactPoint(host2) .withLoadBalancingPolicy(new TokenAwarePolicy( DCAwareRoundRobinPolicy.builder().withLocalDc("dc1").build()));

Conclusion

En résumé, il y a deux méthodes pour définir le DC local d’un client:

  1. lui fournir des points de contact qui sont tous dans le datacenter local;
  2. lui spécifier explicitement le datacenter local.

Cas de Spark

Lorsqu’on utilise le Cassandra Connector depuis Spark et qu’on souhaite isoler le traitement sur un datacenter particulier, le plus fiable est d’indiquer le datacenter de traitement en paramètre spark.cassandra.connection.local_dc.

Vous souhaitez tout savoir du Big Data (architectures, solutions, freins et opportunités…) ? Découvrez notre livre blanc Big Data !