Stellen Sie sich OpenSearch wie eine moderne Stadt vor. Genau wie eine Stadt aus verschiedenen Vierteln, Straßen und Gebäuden besteht, die alle zusammenarbeiten müssen, um das tägliche Leben zu ermöglichen, besteht OpenSearch aus verschiedenen Komponenten, die harmonisch zusammenspielen, um Suchanfragen effizient zu verarbeiten und Daten sicher zu speichern.
OpenSearch wurde von Grund auf als verteiltes System entwickelt. Das bedeutet, dass es seine Arbeit auf mehrere Server (Nodes) verteilen kann, ähnlich wie eine große Organisation verschiedene Abteilungen hat, die unterschiedliche Aufgaben übernehmen. Dieses Design bietet drei wesentliche Vorteile:
In einer OpenSearch-Umgebung gibt es verschiedene Arten von Nodes, jeder mit einer spezialisierten Aufgabe. Denken Sie dabei an spezialisierte Abteilungen in einem Unternehmen.
Coordinating Nodes in OpenSearch sind Knoten, die keine Daten speichern oder Indexierungsaufgaben durchführen, sondern sich darauf konzentrieren, Such- und Schreibanfragen zu koordinieren und weiterzuleiten. Sie spielen eine zentrale Rolle bei der Verteilung und Aggregation von Aufgaben im Cluster.
Ein Coordinating Node wird durch Deaktivieren aller anderen Rollen konfiguriert:
node.master: false
node.data: false
node.ingest: falseDadurch wird der Knoten zu einem reinen Coordinating Node.
Master Nodes sind wie die Geschäftsführung eines Unternehmens. Sie treffen wichtige Entscheidungen über:
Eine typische Master-Node-Konfiguration sieht so aus:
{
"node.roles": ["master"],
"cluster.initial_master_nodes": [
"master-1",
"master-2",
"master-3"
],
"discovery.seed_hosts": [
"master-1:9300",
"master-2:9300",
"master-3:9300"
],
"node.attr.availability_zone": "zone-1"
}
Diese Konfiguration zeigt wichtige Aspekte:
Data Nodes sind wie die Lagerhallen eines Unternehmens. Sie speichern die eigentlichen Daten und führen:
Data Nodes konfigurieren wir beispielsweise so:
{
"node.roles": ["data"],
"node.attr.data_type": "hot",
"node.attr.box_type": "memory_optimized",
"indices.memory.index_buffer_size": "30%",
"indices.queries.cache.size": "25%",
"thread_pool.write.queue_size": 1000,
"thread_pool.search.queue_size": 1000
}
Diese Konfiguration zeigt:
Nur Master Nodes sind zwingend erforderlich. Coordination- und Data Nodes sind optional. Ein OpenSearch-Cluster kann minimal aus einem einzigen Master Node bestehen, erreicht dann jedoch aufgrund fehlender Redundanz nicht den Status Green. Nodes können dem Cluster hinzugefügt oder entfernt werden. Der Cluster organisiert sich dabei selbst.
Es ist beispielsweise möglich, einen Master Node auszutauschen, indem ein neuer Master hinzugefügt wird. Sobald dieser den Status Green erreicht hat, kann ein anderer Master entfernt werden. ## Die Datenspeicherung verstehen
OpenSearch verteilt Daten intelligent über das Cluster. Stellen Sie sich das wie ein modernes Bibliothekssystem vor, das Bücher nicht nur in einem Regal, sondern in verschiedenen Abteilungen und Stockwerken aufbewahrt.
Ein Index in OpenSearch wird in Shards aufgeteilt. Dies ist vergleichbar mit dem Aufteilen eines dicken Buches in mehrere Bände, damit mehrere Menschen gleichzeitig darin lesen können.
Die Shard-Konfiguration erfolgt bei der Index-Erstellung:
PUT /customer_data
{
"settings": {
"index": {
"number_of_shards": 5,
"number_of_replicas": 1,
"routing.allocation.total_shards_per_node": 3,
"routing.allocation.awareness.attributes": "availability_zone",
"routing.allocation.awareness.force.zone.values": "zone1,zone2",
"index.unassigned.node_left.delayed_timeout": "5m",
}
}
}
Diese Konfiguration zeigt fortgeschrittene Konzepte:
Das Routing-System in OpenSearch entscheidet, wo Daten gespeichert und gesucht werden. Dies ist wie ein intelligentes Navigationssystem, das den besten Weg zu den gesuchten Informationen findet.
Ein Beispiel für benutzerdefiniertes Routing:
PUT /orders/_doc/1?routing=customer_123
{
"order_id": "ORDER-1",
"customer_id": "customer_123",
"amount": 157.35,
"items": [...]
}
Dieses Routing sorgt dafür, dass:
OpenSearch implementiert verschiedene Strategien für Hochverfügbarkeit, ähnlich wie ein Unternehmen verschiedene Sicherheitsmaßnahmen kombiniert.
Jedes Shard existiert als Primary und mindestens eine Replica:
PUT /logs_2024
{
"settings": {
"index": {
"number_of_shards": 3,
"number_of_replicas": 2,
"routing.allocation.include._tier_preference": "data_hot",
"index.routing.allocation.require.box_type": "memory_optimized",
"index.routing.allocation.total_shards_per_node": 2,
"index.lifecycle.name": "logs_policy",
"index.recovery.max_bytes_per_sec": "40mb"
}
}
}
Diese Konfiguration demonstriert:
Der Cluster-Zustand ist wie das Nervensystem von OpenSearch. Er enthält wichtige Informationen über:
Ein Beispiel für Cluster-Einstellungen:
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "85%",
"cluster.routing.allocation.disk.watermark.high": "90%",
"cluster.routing.allocation.disk.watermark.flood_stage": "95%",
"cluster.routing.allocation.awareness.attributes": "zone",
"cluster.routing.allocation.balance.shard": 0.7,
"cluster.routing.allocation.balance.index": 0.6
}
}
Diese Einstellungen zeigen:
Die Performance-Optimierung in OpenSearch ist wie das Feintuning eines Rennwagens - viele kleine Anpassungen ergeben zusammen einen großen Effekt.
Der Umgang mit Arbeitsspeicher ist kritisch:
# JVM-Einstellungen in jvm.options
-Xms31g
-Xmx31g
-XX:+UseG1GC
-XX:G1ReservePercent=25
-XX:InitiatingHeapOccupancyPercent=75
-XX:+ParallelRefProcEnabled
-XX:MaxGCPauseMillis=200
Diese Einstellungen zeigen:
Verschiedene Cache-Typen müssen balanciert werden:
{
"indices.memory.index_buffer_size": "15%",
"indices.queries.cache.size": "20%",
"indices.fielddata.cache.size": "25%",
"indices.breaker.total.limit": "70%",
"indices.breaker.fielddata.limit": "40%",
"indices.breaker.request.limit": "30%"
}
Dies demonstriert: