Dans cet article, je propose une solution afin de réaliser des recherches NRT (Near Real Time Search) dans une collection constituée uniquement de replicas TLOG. J’annonce directement la contrainte afin d’éviter les déceptions en cours de lecture. Il est nécessaire d’être dans un contexte de développement Java / SolrJ !
Pourquoi ne pas utiliser des replicas NRT si les recherches NRT sont nécessaires ? Car si les recherches impérativement NRT représentent un faible pourcentages des requêtes globales, autant profiter du grand avantage des replicas TLOG, à savoir l’économie de ressources CPU et mémoire lors des indexations.
Recherches NRT et Replicas TLOG
Dans un article récent, j’explique ce qu’est et n’est pas une recherche NRT et ce que sont les différents types de replicas de Solr.
Principe de la solution
Le principe de la solution est d’exécuter les recherches uniquement dans les replicas leaders. Les replicas TLOG leaders réalisent les indexations et ils respectent les configurations des autoCommit et autoSoftCommit. De fait, ils sont des replicas NRT. Rechercher uniquement dans des replicas leaders permet donc de réaliser des recherches NRT.
Des recherches encore plus « NRT » !
Ah oui ?
Lorsque les replicas sont de type NRT, le processus d’indexation est le suivant :
- SolrJ envoi chaque document directement au leader du shard cible (sur la base de l’id unique, SolrJ sait quel est le shard cible)
- Le leader transmet le document aux autres replicas NRT et indexe le document
- Tous les replicas indexent et consomment des ressources (CPU et mémoire)
- Le leader attend la confirmation des indexations par les autres replicas NRT
- Une fois toutes les confirmations reçues, le leader retourne le statut de l’indexation au client
Lorsque les replicas sont de type TLOG, le processus d’indexation est le suivant :
- SolrJ envoi chaque document directement au leader du shard cible (sur la base de l’id unique, SolrJ sait quel est le shard cible)
- Le leader (et uniquement lui) index le document et retourne immédiatement le statut de l’indexation au client
- Les autres replicas TLOG se synchronisent à un rythme défini par les configurations autoCommit ou autoSoftCommit
On gagne des millisecondes là et on préserve beaucoup de ressources !
Cas d’usage
L’ensemble des recherches réalisées dans une collection constituée uniquement de replicas TLOG ne peuvent pas être NRT. En effet, la majorité des recherche devront utiliser l’ensemble des replicas. Forcer uniquement des recherches dans les replicas leader doit être réservé à des besoins bien particuliers. Pour deux de mes missions récentes, les méthodes en place nécessitaient des recherches NRT que très ponctuellement et cela dans la chaine d’alimentation des collections.
Cas 1 : Dédoublonnage
Pour cet organisme public, les données de proviennent de différentes sources. Chaque source pouvant quasi-simultanément fournir un nouveau document ou des enrichissements d’un document existant. Le besoin est de de pouvoir détecter en moins d’une seconde les créations ou modifications sur un document dans la collection afin d’éviter la génération de doublons ou l’écrasement de modifications.
Cas 2 : Indexation en deux passes
Afin de pas remettre en cause un workflow d’indexation de documents en deux passes (création puis enrichissement), il est nécessaire de pouvoir enrichir dés que possible (idéalement dans un délai maximum 200 millisecondes) un document qui vient d’être ajouté à la collection et permettre ainsi une indexation initiale rapide de plusieurs centaines de millions de documents.
Mise en œuvre de la solution
La solution consiste à récupérer la liste des réplicas leaders d’une collection. Pour cela il est nécessaire d’utiliser la librairie SolrJ et d’utiliser un objet CloudSolrClient qui peut connaitre l’état des collections au moyen de Zookeeper. Voici un exemple de code permettant de récupérer cette liste avec SolrJ version 8.
#
# Solr 8 - Java sample in order to get shards leaders for a collection
#
package fr.eolya.solr.tests;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.zookeeper.KeeperException;
import java.util.*;
public class GetLeaders {
public static void main(String[] args){
final List<String> zkServers = new ArrayList<String>();
zkServers.add("zk1:2181");
zkServers.add("zk2:2181");
zkServers.add("zk3:2181");
CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder(zkServers, Optional.empty()).build();
try {
Map<String, String> leaders = getShardLeaders(cloudSolrClient, "sirene");
for (String leader: leaders.values()) {
System.out.println(leader);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
}
}
static private Map<String, String> getShardLeaders(CloudSolrClient cloudSolrClient, String collection) throws InterruptedException, KeeperException {
Map<String, String> shardleaders = new TreeMap<String, String>();
ZkStateReader zkStateReader = cloudSolrClient.getZkStateReader();
for (Slice slice : zkStateReader.getClusterState().getCollection(collection).getSlices()) {
shardleaders.put(slice.getName(), zkStateReader.getLeaderUrl(collection, slice.getName(), 30000));
}
return shardleaders;
}
}
L’exécution de ce code affiche les réplicas leaders
http://solr2:8983/solr/sirene_shard1_replica_t2/
http://solr1:8983/solr/sirene_shard2_replica_t4/
Une fois que l’on dispose de la liste des réplicas leaders, il est alors possible d’en forcer l’utilisation dans une requête au moyen du paramètre « shards »
http://localhost:8983/solr/sirene/select?q=*:*&shards=solr2:8983/solr/sirene_shard1_replica_t2,solr1:8983/solr/sirene_shard2_replica_t4
Idéalement, l’état de la collection n’est pas récupérée avant chaque requête, une mise en cache de quelques minutes doit être mise en en place. Si avant la fin du délai de validité du cache un nœud Solr qui héberge un leader devient indisponible, les requêtes échouent et une relecture de l’état de la collection doit être faite. Attention, une commande REBALANCELEADERS n’est pas détectée car elle ne provoque pas d’erreur de recherche !
Conclusion
Pour des cas d’usages très précis qui correspondent à un faible taux de la quantité globale des requêtes, il est possible de réaliser des recherches « NRT » avec uniquement des replicas TLOG.
Vous souhaitez bénéficier d’une expertise Solr ou intégrer une ressource ponctuelle à vos projets ? Rendez vous sur la page Contact |