Elasticsearch Installation: Complete Search and Analytics Engine Setup Guide
Elasticsearch is a distributed, RESTful search and analytics engine built on Apache Lucene, designed to handle massive volumes of data with near real-time search capabilities. As the heart of the Elastic Stack (formerly ELK Stack), Elasticsearch powers everything from simple site search to complex log analysis, business intelligence, and security analytics. This comprehensive guide provides detailed instructions for installing, configuring, and optimizing Elasticsearch for production use.
Introduction
In the modern data landscape, the ability to search, analyze, and visualize large volumes of data quickly is crucial for business success. Elasticsearch addresses this need by providing a powerful, scalable platform for full-text search, structured data analysis, and time-series data management.
What Makes Elasticsearch Powerful?
Full-Text Search: Advanced search capabilities with relevance scoring, fuzzy matching, and complex query support enable sophisticated search experiences comparable to major search engines.
Near Real-Time: Documents become searchable within seconds of indexing, enabling real-time analytics and monitoring dashboards.
Distributed Architecture: Horizontal scaling across multiple nodes provides high availability and the ability to handle petabytes of data.
Schema-Free JSON Documents: Store and search complex, nested JSON documents without predefined schemas, adapting dynamically to your data structure.
RESTful API: Simple HTTP-based API makes integration with any programming language straightforward.
Powerful Aggregations: Complex analytics, statistics, and grouping operations rival traditional business intelligence tools.
Common Use Cases
- Application Search: Power website and application search features with relevance tuning
- Log and Event Data Analysis: Centralize and analyze logs from distributed systems
- Security Analytics: Detect threats and anomalies in security event data
- Business Analytics: Analyze business metrics and generate insights from operational data
- Monitoring and Observability: Track system performance and application metrics
- E-commerce Product Search: Implement faceted search with filters and recommendations
- Geospatial Analysis: Search and analyze location-based data
This guide focuses on production-ready Elasticsearch installation with security, performance optimization, and best practices.
Prerequisites
Elasticsearch has specific requirements that must be met before installation.
System Requirements
Minimum Requirements (Development/Testing):
- Linux server (Ubuntu 20.04+, Debian 11+, CentOS 8+, Rocky Linux 8+)
- 2 CPU cores
- 4GB RAM
- 20GB disk space
- Java 11 or higher (OpenJDK or Oracle JDK)
Recommended for Production:
- 4+ CPU cores (8+ for heavy workloads)
- 16GB+ RAM (32GB+ recommended)
- SSD storage with 100GB+ available space
- Dedicated Elasticsearch nodes (not shared with applications)
- Multiple nodes for high availability (3+ nodes recommended)
Memory Planning
Elasticsearch is memory-intensive. Follow these guidelines:
Heap Memory:
- Set to 50% of available RAM (maximum 32GB per node)
- Never exceed 32GB heap (compressed pointers disabled above 32GB)
- Reserve remaining RAM for Lucene file system cache
Calculation Example:
- Server with 64GB RAM: Set heap to 31GB, leaving 33GB for OS and file cache
- Server with 16GB RAM: Set heap to 8GB, leaving 8GB for OS and file cache
Storage Requirements
Storage Planning:
- Calculate expected data size: daily ingest rate × retention days × 1.25 (overhead)
- Use SSDs for production (10x+ performance improvement over HDDs)
- Plan for 20-30% free disk space for merges and optimization
Example Calculation:
- Daily ingest: 50GB
- Retention: 30 days
- Required storage: 50GB × 30 × 1.25 = 1,875GB (~2TB)
Network Requirements
- Port 9200 (HTTP API) accessible from client applications
- Port 9300 (Transport layer) for inter-node communication
- Low-latency network for multi-node clusters
- Firewall configured to restrict external access
Software Prerequisites
- Java Development Kit (JDK) 11 or higher
- Root or sudo access
- Curl or wget for testing
- Text editor (vim, nano, etc.)
Installation
Method 1: Package Repository Installation (Recommended)
Using official Elasticsearch repositories ensures you receive updates and security patches.
Ubuntu/Debian Installation
Step 1: Import Elasticsearch GPG Key
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
Step 2: Add Elasticsearch Repository
sudo apt install -y apt-transport-https
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
Step 3: Update Package Index
sudo apt update
Step 4: Install Elasticsearch
sudo apt install -y elasticsearch
The installation will generate a random password for the elastic superuser and enrollment token. Save these securely:
--------------------------- Security autoconfiguration information ----------------------------
Authentication and authorization are enabled.
TLS for the transport and HTTP layers is enabled and configured.
The generated password for the elastic built-in superuser is: ABC123xyz789==
If this node should join an existing cluster, you can reconfigure this with
'/usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token <token-here>'
after creating an enrollment token on your existing cluster.
You can complete the following actions at any time:
Reset the password of the elastic built-in superuser with
'/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic'.
Generate an enrollment token for Kibana instances with
'/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana'.
Generate an enrollment token for Elasticsearch nodes with
'/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node'.
---------------------------------------------------------------------------------------------------
Step 5: Configure System to Start Elasticsearch
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
CentOS/Rocky Linux Installation
Step 1: Import Elasticsearch GPG Key
sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
Step 2: Create Repository File
sudo tee /etc/yum.repos.d/elasticsearch.repo << 'EOF'
[elasticsearch]
name=Elasticsearch repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
EOF
Step 3: Install Elasticsearch
sudo dnf install -y elasticsearch
Step 4: Enable and Start Service
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
Method 2: Manual Archive Installation
For custom installations or non-standard environments:
Download and Extract
# Download Elasticsearch (check https://www.elastic.co/downloads/elasticsearch for latest version)
cd /tmp
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.11.0-linux-x86_64.tar.gz
# Extract
sudo tar -xzf elasticsearch-8.11.0-linux-x86_64.tar.gz -C /opt/
sudo mv /opt/elasticsearch-8.11.0 /opt/elasticsearch
# Create elasticsearch user
sudo useradd -r -s /bin/false elasticsearch
# Set ownership
sudo chown -R elasticsearch:elasticsearch /opt/elasticsearch
Create Systemd Service
Create /etc/systemd/system/elasticsearch.service:
[Unit]
Description=Elasticsearch
Documentation=https://www.elastic.co
Wants=network-online.target
After=network-online.target
[Service]
Type=notify
RuntimeDirectory=elasticsearch
PrivateTmp=true
Environment=ES_HOME=/opt/elasticsearch
Environment=ES_PATH_CONF=/opt/elasticsearch/config
Environment=PID_DIR=/var/run/elasticsearch
Environment=ES_SD_NOTIFY=true
WorkingDirectory=/opt/elasticsearch
User=elasticsearch
Group=elasticsearch
ExecStart=/opt/elasticsearch/bin/elasticsearch
StandardOutput=journal
StandardError=inherit
LimitNOFILE=65535
LimitNPROC=4096
LimitAS=infinity
LimitFSIZE=infinity
TimeoutStopSec=0
KillMode=process
KillSignal=SIGTERM
SendSIGKILL=no
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
Method 3: Docker Installation
For containerized environments:
# Create network
docker network create elastic
# Run Elasticsearch
docker run -d \
--name elasticsearch \
--net elastic \
-p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e "ES_JAVA_OPTS=-Xms2g -Xmx2g" \
-v es-data:/usr/share/elasticsearch/data \
docker.elastic.co/elasticsearch/elasticsearch:8.11.0
# Get generated password
docker logs elasticsearch | grep "Password for the elastic user"
Post-Installation Verification
# Check service status
sudo systemctl status elasticsearch
# Wait for Elasticsearch to start (may take 30-60 seconds)
sleep 30
# Test connection (use generated password)
curl -k -u elastic:YOUR_GENERATED_PASSWORD https://localhost:9200
# Expected output shows cluster information
Configuration
Elasticsearch configuration is primarily managed through elasticsearch.yml and JVM options.
Main Configuration File
Location: /etc/elasticsearch/elasticsearch.yml (package installation) or /opt/elasticsearch/config/elasticsearch.yml (manual installation)
Essential Configuration Settings
Cluster and Node Configuration
# Cluster name (all nodes in cluster must have same name)
cluster.name: production-cluster
# Node name (unique for each node)
node.name: es-node-1
# Node roles (master, data, ingest, ml, etc.)
node.roles: [master, data, ingest]
# Network settings
network.host: 0.0.0.0
http.port: 9200
transport.port: 9300
# Discovery settings (for single node)
discovery.type: single-node
# Discovery settings (for multi-node cluster)
# discovery.seed_hosts: ["es-node-1", "es-node-2", "es-node-3"]
# cluster.initial_master_nodes: ["es-node-1", "es-node-2", "es-node-3"]
Path Configuration
# Data directory (can specify multiple for multiple disks)
path.data: /var/lib/elasticsearch
# Logs directory
path.logs: /var/log/elasticsearch
Memory Settings
# Lock memory to prevent swapping
bootstrap.memory_lock: true
Security Configuration (Elasticsearch 8.x)
Elasticsearch 8.x enables security by default:
# Security features
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
# SSL/TLS for HTTP
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/http.p12
# SSL/TLS for transport layer
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/transport.p12
xpack.security.transport.ssl.truststore.path: certs/transport.p12
JVM Heap Size Configuration
Edit /etc/elasticsearch/jvm.options or /etc/elasticsearch/jvm.options.d/custom.options:
# Set heap size (50% of RAM, max 32GB)
-Xms8g
-Xmx8g
# For production with 32GB+ RAM
-Xms31g
-Xmx31g
Important Rules:
- Set Xms and Xmx to the same value
- Don't exceed 32GB (compressed pointers disabled above this)
- Set to 50% of available RAM
- Leave remaining RAM for file system cache
System Configuration
Disable Swapping
Swapping severely degrades Elasticsearch performance.
Method 1: Disable Swap Completely
sudo swapoff -a
# Make permanent
sudo sed -i '/ swap / s/^/#/' /etc/fstab
Method 2: Configure Swappiness
sudo sysctl -w vm.swappiness=1
echo "vm.swappiness=1" | sudo tee -a /etc/sysctl.conf
Increase File Descriptors
# Check current limits
ulimit -n
# Set for elasticsearch user
sudo tee -a /etc/security/limits.conf << EOF
elasticsearch soft nofile 65536
elasticsearch hard nofile 65536
elasticsearch soft nproc 4096
elasticsearch hard nproc 4096
elasticsearch soft memlock unlimited
elasticsearch hard memlock unlimited
EOF
For systemd services, limits are already configured in the service file.
Virtual Memory Settings
# Increase virtual memory map count
sudo sysctl -w vm.max_map_count=262144
# Make permanent
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
Firewall Configuration
UFW (Ubuntu/Debian)
# Allow from specific application servers
sudo ufw allow from 192.168.1.0/24 to any port 9200 proto tcp
# Allow inter-node communication (for clusters)
sudo ufw allow from 192.168.1.0/24 to any port 9300 proto tcp
# Reload firewall
sudo ufw reload
firewalld (CentOS/Rocky)
# Create zone for Elasticsearch
sudo firewall-cmd --permanent --new-zone=elasticsearch
sudo firewall-cmd --permanent --zone=elasticsearch --add-source=192.168.1.0/24
sudo firewall-cmd --permanent --zone=elasticsearch --add-port=9200/tcp
sudo firewall-cmd --permanent --zone=elasticsearch --add-port=9300/tcp
# Reload firewall
sudo firewall-cmd --reload
Security Configuration
Reset Elastic User Password
# Reset password for elastic superuser
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic -i
# Or auto-generate
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic
Create Additional Users
# Create user with specific role
sudo /usr/share/elasticsearch/bin/elasticsearch-users useradd myuser -r superuser
# Create user with custom role
sudo /usr/share/elasticsearch/bin/elasticsearch-users useradd readonly_user -r viewer
Disable Security (Not Recommended for Production)
Only for development/testing:
Edit /etc/elasticsearch/elasticsearch.yml:
xpack.security.enabled: false
xpack.security.enrollment.enabled: false
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false
Restart Elasticsearch:
sudo systemctl restart elasticsearch
Performance Tuning
Index-Level Settings
Create index with optimal settings:
curl -k -u elastic:password -X PUT "https://localhost:9200/myindex" -H 'Content-Type: application/json' -d'
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"refresh_interval": "30s",
"index.codec": "best_compression"
}
}
'
Thread Pool Configuration
Add to elasticsearch.yml:
thread_pool:
write:
queue_size: 1000
search:
queue_size: 1000
Restart Elasticsearch
After configuration changes:
sudo systemctl restart elasticsearch
# Verify startup
sudo journalctl -u elasticsearch -f
Practical Examples
Example 1: Creating and Querying Index
Create Index:
curl -k -u elastic:password -X PUT "https://localhost:9200/products" -H 'Content-Type: application/json' -d'
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"name": { "type": "text" },
"description": { "type": "text" },
"price": { "type": "float" },
"category": { "type": "keyword" },
"created_at": { "type": "date" }
}
}
}
'
Index Documents:
# Index single document
curl -k -u elastic:password -X POST "https://localhost:9200/products/_doc/1" -H 'Content-Type: application/json' -d'
{
"name": "Laptop Pro 15",
"description": "High performance laptop with 16GB RAM",
"price": 1299.99,
"category": "Electronics",
"created_at": "2024-01-15"
}
'
# Bulk indexing
curl -k -u elastic:password -X POST "https://localhost:9200/products/_bulk" -H 'Content-Type: application/json' -d'
{"index":{"_id":"2"}}
{"name":"Wireless Mouse","description":"Ergonomic wireless mouse","price":29.99,"category":"Electronics","created_at":"2024-01-16"}
{"index":{"_id":"3"}}
{"name":"USB-C Cable","description":"High speed USB-C charging cable","price":12.99,"category":"Accessories","created_at":"2024-01-17"}
'
Search Documents:
# Simple search
curl -k -u elastic:password -X GET "https://localhost:9200/products/_search?q=laptop"
# Complex search with query DSL
curl -k -u elastic:password -X GET "https://localhost:9200/products/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"bool": {
"must": [
{ "match": { "description": "wireless" } }
],
"filter": [
{ "range": { "price": { "lte": 50 } } }
]
}
},
"sort": [
{ "price": { "order": "asc" } }
]
}
'
Example 2: Log Ingestion and Analysis
Create Logs Index with Date Pattern:
curl -k -u elastic:password -X PUT "https://localhost:9200/logs-2024.01.15" -H 'Content-Type: application/json' -d'
{
"settings": {
"number_of_shards": 2,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"timestamp": { "type": "date" },
"level": { "type": "keyword" },
"message": { "type": "text" },
"service": { "type": "keyword" },
"host": { "type": "keyword" },
"response_time": { "type": "integer" }
}
}
}
'
Index Log Entries:
curl -k -u elastic:password -X POST "https://localhost:9200/logs-2024.01.15/_bulk" -H 'Content-Type: application/json' -d'
{"index":{}}
{"timestamp":"2024-01-15T10:00:00","level":"INFO","message":"User logged in","service":"auth","host":"web-1","response_time":45}
{"index":{}}
{"timestamp":"2024-01-15T10:01:00","level":"ERROR","message":"Database connection failed","service":"api","host":"web-2","response_time":5000}
{"index":{}}
{"timestamp":"2024-01-15T10:02:00","level":"WARN","message":"High memory usage detected","service":"monitor","host":"web-1","response_time":120}
'
Analyze Logs:
# Count errors by service
curl -k -u elastic:password -X GET "https://localhost:9200/logs-*/_search" -H 'Content-Type: application/json' -d'
{
"size": 0,
"query": {
"term": { "level": "ERROR" }
},
"aggs": {
"errors_by_service": {
"terms": { "field": "service" }
}
}
}
'
# Average response time by hour
curl -k -u elastic:password -X GET "https://localhost:9200/logs-*/_search" -H 'Content-Type: application/json' -d'
{
"size": 0,
"aggs": {
"response_times": {
"date_histogram": {
"field": "timestamp",
"calendar_interval": "hour"
},
"aggs": {
"avg_response": {
"avg": { "field": "response_time" }
}
}
}
}
}
'
Example 3: Full-Text Search with Relevance
Create Articles Index:
curl -k -u elastic:password -X PUT "https://localhost:9200/articles" -H 'Content-Type: application/json' -d'
{
"settings": {
"analysis": {
"analyzer": {
"english_analyzer": {
"type": "standard",
"stopwords": "_english_"
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "english_analyzer",
"boost": 2.0
},
"content": {
"type": "text",
"analyzer": "english_analyzer"
},
"tags": { "type": "keyword" },
"author": { "type": "keyword" },
"published_date": { "type": "date" }
}
}
}
'
Search with Highlighting:
curl -k -u elastic:password -X GET "https://localhost:9200/articles/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"multi_match": {
"query": "elasticsearch performance",
"fields": ["title^2", "content"],
"type": "best_fields"
}
},
"highlight": {
"fields": {
"title": {},
"content": {}
}
},
"size": 10
}
'
Example 4: Aggregations and Analytics
Sales Analytics Example:
# Complex aggregation query
curl -k -u elastic:password -X GET "https://localhost:9200/sales/_search" -H 'Content-Type: application/json' -d'
{
"size": 0,
"aggs": {
"sales_over_time": {
"date_histogram": {
"field": "sale_date",
"calendar_interval": "month"
},
"aggs": {
"total_revenue": {
"sum": { "field": "amount" }
},
"average_sale": {
"avg": { "field": "amount" }
},
"top_products": {
"terms": {
"field": "product_name",
"size": 5
},
"aggs": {
"product_revenue": {
"sum": { "field": "amount" }
}
}
}
}
}
}
}
'
Example 5: Python Integration
Using Elasticsearch Python Client:
from elasticsearch import Elasticsearch
from datetime import datetime
# Connect to Elasticsearch
es = Elasticsearch(
['https://localhost:9200'],
basic_auth=('elastic', 'your_password'),
verify_certs=False
)
# Index document
doc = {
'title': 'Elasticsearch Guide',
'content': 'Learn how to use Elasticsearch effectively',
'author': 'John Doe',
'published_date': datetime.now(),
'tags': ['elasticsearch', 'search', 'tutorial']
}
response = es.index(index='articles', document=doc)
print(f"Indexed document ID: {response['_id']}")
# Search documents
search_query = {
'query': {
'match': {
'content': 'elasticsearch'
}
}
}
results = es.search(index='articles', body=search_query)
print(f"Found {results['hits']['total']['value']} results")
for hit in results['hits']['hits']:
print(f"- {hit['_source']['title']}")
# Aggregation
agg_query = {
'size': 0,
'aggs': {
'tags_count': {
'terms': {
'field': 'tags',
'size': 10
}
}
}
}
agg_results = es.search(index='articles', body=agg_query)
for bucket in agg_results['aggregations']['tags_count']['buckets']:
print(f"{bucket['key']}: {bucket['doc_count']}")
Verification
Basic Health Checks
# Cluster health
curl -k -u elastic:password "https://localhost:9200/_cluster/health?pretty"
# Node information
curl -k -u elastic:password "https://localhost:9200/_nodes?pretty"
# Cluster statistics
curl -k -u elastic:password "https://localhost:9200/_cluster/stats?pretty"
# Index information
curl -k -u elastic:password "https://localhost:9200/_cat/indices?v"
# Node statistics
curl -k -u elastic:password "https://localhost:9200/_cat/nodes?v"
Performance Testing
# Install esrally (Elasticsearch benchmarking tool)
pip3 install esrally
# Run benchmark
esrally race --track=geonames --target-hosts=localhost:9200 --client-options="basic_auth_user:'elastic',basic_auth_password:'password',verify_certs:false"
Monitor Resource Usage
# Check JVM heap usage
curl -k -u elastic:password "https://localhost:9200/_cat/nodes?v&h=name,heap.percent,heap.current,heap.max,ram.percent,ram.current,ram.max"
# Check disk usage
curl -k -u elastic:password "https://localhost:9200/_cat/allocation?v"
# Check thread pools
curl -k -u elastic:password "https://localhost:9200/_cat/thread_pool?v&h=node_name,name,active,queue,rejected,completed"
Troubleshooting
Issue 1: Elasticsearch Won't Start
Symptom: Service fails to start
Solution:
# Check logs
sudo journalctl -u elasticsearch -n 100 --no-pager
# Common issues and fixes:
# 1. Insufficient memory
# Check available memory
free -h
# Reduce heap size in /etc/elasticsearch/jvm.options
# 2. Port already in use
sudo ss -tlnp | grep 9200
# Kill process or change port in elasticsearch.yml
# 3. Permission issues
sudo chown -R elasticsearch:elasticsearch /var/lib/elasticsearch
sudo chown -R elasticsearch:elasticsearch /var/log/elasticsearch
sudo chown -R elasticsearch:elasticsearch /etc/elasticsearch
# 4. vm.max_map_count too low
sudo sysctl -w vm.max_map_count=262144
Issue 2: High Memory Usage
Symptom: Elasticsearch consuming too much memory or experiencing OOM errors
Solution:
# Check current heap usage
curl -k -u elastic:password "https://localhost:9200/_nodes/stats/jvm?pretty"
# Reduce heap size if too high
sudo nano /etc/elasticsearch/jvm.options
# Set appropriate values:
# -Xms8g
# -Xmx8g
# Clear field data cache
curl -k -u elastic:password -X POST "https://localhost:9200/_cache/clear?fielddata=true"
# Check for memory leaks
curl -k -u elastic:password "https://localhost:9200/_nodes/stats/indices/fielddata?fields=*&pretty"
# Restart service
sudo systemctl restart elasticsearch
Issue 3: Slow Queries
Symptom: Search queries taking too long
Solution:
# Enable slow log
curl -k -u elastic:password -X PUT "https://localhost:9200/myindex/_settings" -H 'Content-Type: application/json' -d'
{
"index.search.slowlog.threshold.query.warn": "10s",
"index.search.slowlog.threshold.query.info": "5s",
"index.search.slowlog.threshold.fetch.warn": "1s",
"index.indexing.slowlog.threshold.index.warn": "10s"
}
'
# Check slow log
sudo tail -f /var/log/elasticsearch/*_index_search_slowlog.log
# Optimize index
curl -k -u elastic:password -X POST "https://localhost:9200/myindex/_forcemerge?max_num_segments=1"
# Check query profile
# Add "profile": true to your search query
Issue 4: Disk Space Issues
Symptom: Cluster going into read-only mode or rejecting writes
Solution:
# Check disk usage
curl -k -u elastic:password "https://localhost:9200/_cat/allocation?v"
# Remove read-only block
curl -k -u elastic:password -X PUT "https://localhost:9200/_all/_settings" -H 'Content-Type: application/json' -d'
{
"index.blocks.read_only_allow_delete": null
}
'
# Delete old indices
curl -k -u elastic:password -X DELETE "https://localhost:9200/logs-2023.*"
# Reduce replica count
curl -k -u elastic:password -X PUT "https://localhost:9200/myindex/_settings" -H 'Content-Type: application/json' -d'
{
"number_of_replicas": 0
}
'
# Increase disk watermark thresholds
curl -k -u elastic:password -X PUT "https://localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "90%",
"cluster.routing.allocation.disk.watermark.high": "95%"
}
}
'
Issue 5: Connection Refused
Symptom: Cannot connect to Elasticsearch
Solution:
# Check if service is running
sudo systemctl status elasticsearch
# Check listening ports
sudo ss -tlnp | grep 9200
# Check network.host setting
sudo grep "network.host" /etc/elasticsearch/elasticsearch.yml
# Temporarily disable firewall for testing
sudo ufw disable # Ubuntu
sudo systemctl stop firewalld # CentOS
# Test local connection
curl -k -u elastic:password https://localhost:9200
# Check SSL certificate issues
curl -v -k -u elastic:password https://localhost:9200
Issue 6: Authentication Failures
Symptom: 401 Unauthorized errors
Solution:
# Reset elastic password
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic
# Test with new password
curl -k -u elastic:NEW_PASSWORD https://localhost:9200
# Check if security is enabled
sudo grep "xpack.security.enabled" /etc/elasticsearch/elasticsearch.yml
# Temporarily disable security (development only)
# Edit /etc/elasticsearch/elasticsearch.yml:
# xpack.security.enabled: false
# sudo systemctl restart elasticsearch
Best Practices
Index Management Best Practices
- Use Index Lifecycle Management (ILM):
curl -k -u elastic:password -X PUT "https://localhost:9200/_ilm/policy/logs_policy" -H 'Content-Type: application/json' -d'
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "50GB",
"max_age": "1d"
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"shrink": {
"number_of_shards": 1
},
"forcemerge": {
"max_num_segments": 1
}
}
},
"delete": {
"min_age": "30d",
"actions": {
"delete": {}
}
}
}
}
}
'
-
Appropriate Shard Sizing:
- Target shard size: 10-50GB
- Avoid too many small shards (overhead)
- Avoid too few large shards (poor distribution)
-
Disable Replicas During Bulk Indexing:
curl -k -u elastic:password -X PUT "https://localhost:9200/myindex/_settings" -H 'Content-Type: application/json' -d'
{
"number_of_replicas": 0,
"refresh_interval": "-1"
}
'
# After bulk indexing complete
curl -k -u elastic:password -X PUT "https://localhost:9200/myindex/_settings" -H 'Content-Type: application/json' -d'
{
"number_of_replicas": 1,
"refresh_interval": "1s"
}
'
Security Best Practices
- Always Enable Security in Production
- Use Role-Based Access Control (RBAC)
- Enable Audit Logging:
xpack.security.audit.enabled: true
- Use TLS/SSL for All Connections
- Regularly Update Passwords
- Implement Network Segmentation
- Restrict Anonymous Access
Performance Best Practices
-
Optimize Mappings:
- Use appropriate field types
- Disable indexing for fields you don't search
- Use
_sourcefiltering for large documents
-
Bulk Operations:
- Use bulk API for indexing multiple documents
- Optimal bulk size: 5-15MB
-
Query Optimization:
- Use filters instead of queries when possible (cacheable)
- Avoid wildcard queries on large datasets
- Use
_sourcefiltering to return only needed fields
-
Monitor and Alert:
- Set up monitoring for cluster health
- Alert on high heap usage (>75%)
- Monitor disk space
- Track query performance
Backup Best Practices
- Configure Snapshot Repository:
# Create backup directory
sudo mkdir -p /backup/elasticsearch
sudo chown elasticsearch:elasticsearch /backup/elasticsearch
# Register snapshot repository
curl -k -u elastic:password -X PUT "https://localhost:9200/_snapshot/my_backup" -H 'Content-Type: application/json' -d'
{
"type": "fs",
"settings": {
"location": "/backup/elasticsearch",
"compress": true
}
}
'
# Create snapshot
curl -k -u elastic:password -X PUT "https://localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true"
# Restore snapshot
curl -k -u elastic:password -X POST "https://localhost:9200/_snapshot/my_backup/snapshot_1/_restore"
- Automated Backup Script:
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
SNAPSHOT_NAME="snapshot_$DATE"
curl -k -u elastic:password -X PUT "https://localhost:9200/_snapshot/my_backup/$SNAPSHOT_NAME?wait_for_completion=false"
# Schedule with cron
# 0 2 * * * /usr/local/bin/elasticsearch-backup.sh
Monitoring Best Practices
-
Key Metrics to Monitor:
- Cluster status (green, yellow, red)
- JVM heap usage
- Disk space
- CPU usage
- Query latency
- Indexing rate
- Search rate
-
Use Elasticsearch Monitoring Features:
- Enable monitoring in Kibana
- Use Metricbeat for system metrics
- Configure alerts for critical conditions
Conclusion
Elasticsearch is a powerful search and analytics engine that, when properly installed and configured, provides exceptional performance and scalability for a wide range of use cases. This comprehensive guide has walked you through the complete process of setting up a production-ready Elasticsearch installation.
Key Takeaways:
Installation: Whether using package managers, manual installation, or Docker, ensure you follow security best practices from the start, including enabling authentication and TLS/SSL encryption.
Configuration: Proper memory allocation, system tuning, and index settings are critical for optimal performance. Remember the 50% heap rule and never exceed 32GB per node.
Security: Elasticsearch 8.x enables security by default, which is essential for production deployments. Always use strong passwords, role-based access control, and network restrictions.
Performance: Optimize shard sizing, use appropriate mappings, leverage bulk operations, and implement index lifecycle management for sustained high performance.
Monitoring: Regular monitoring of cluster health, resource usage, and query performance helps identify issues before they impact users.
Backups: Implement automated snapshot strategies to protect against data loss and enable disaster recovery.
Elasticsearch's versatility makes it suitable for everything from simple website search to complex log analytics and business intelligence. By following the best practices outlined in this guide, you've established a solid foundation for leveraging Elasticsearch's full potential.
As your data grows and requirements evolve, Elasticsearch scales with you through clustering, index optimization, and advanced features. Continue learning about Elasticsearch's rich ecosystem, including Kibana for visualization, Logstash for data processing, and Beats for data shipping.
Your Elasticsearch installation is now ready to power fast, relevant search experiences and deliver actionable insights from your data. Monitor, optimize, and iterate on your configuration as you learn what works best for your specific use cases.
Welcome to the world of powerful, scalable search and analytics with Elasticsearch!


