调用ElasticClient.Indices.Create()后出现未分配索引的问题排查
索引创建后出现未分配分片的原因与解决办法
我用以下C#代码在Elasticsearch中创建索引,但没有生成已分配的索引,反而出现了一个同名的未分配索引,我不需要这个未分配索引。我的elasticsearch.yml是默认配置(如下),请问原因是什么,怎么避免?
ElasticClient.Indices.Create("1234.attachments", c => c .Settings(s => s .Analysis(a => a .Analyzers(ad => ad .Custom("windows_path_hierarchy_analyzer", ca => ca .Tokenizer("windows_path_hierarchy_tokenizer") ) ) .Tokenizers(t => t .PathHierarchy("windows_path_hierarchy_tokenizer", ph => ph .Delimiter('\\') ) .NGram("ngram_tokenizer", td => td .MinGram(3) .MaxGram(3) .TokenChars( TokenChar.Letter, TokenChar.Digit, TokenChar.Symbol) ) ) ) ) .Map<ElasticDocument>(mp => mp .AutoMap() .Properties(ps => ps .Text(s => s .Name(n => n.Doname) .Analyzer("windows_path_hierarchy_analyzer") ) .Object<Attachment>(a => a .Name(n => n.Attachment) .AutoMap() ) ) ) );
Kibana查询语句:
GET _cat/shards?v=true&h=index,shard,prirep,state,node,unassigned.reason&s=state

elasticsearch.yml配置:
# ======================== Elasticsearch Configuration ========================= # # NOTE: Elasticsearch comes with reasonable defaults for most settings. # Before you set out to tweak and tune the configuration, make sure you # understand what are you trying to accomplish and the consequences. # # The primary way of configuring a node is via this file. This template lists # the most important settings you may want to configure for a production cluster. # # Please consult the documentation for further information on configuration options: # https://www.elastic.co/guide/en/elasticsearch/reference/index.html # # ---------------------------------- Cluster ----------------------------------- # # Use a descriptive name for your cluster: # #cluster.name: my-application # # ------------------------------------ Node ------------------------------------ # # Use a descriptive name for the node: # #node.name: node-1 # # Add custom attributes to the node: # #node.attr.rack: r1 # # ----------------------------------- Paths ------------------------------------ # # Path to directory where to store the data (separate multiple locations by comma): # #path.data: /path/to/data # # Path to log files: # #path.logs: /path/to/logs # # ----------------------------------- Memory ----------------------------------- # # Lock the memory on startup: # #bootstrap.memory_lock: true # # Make sure that the heap size is set to about half the memory available # on the system and that the owner of the process is allowed to use this # limit. # # Elasticsearch performs poorly when the system is swapping the memory. # # ---------------------------------- Network ----------------------------------- # # By default Elasticsearch is only accessible on localhost. Set a different # address here to expose this node on the network: # #network.host: 192.168.0.1 # # By default Elasticsearch listens for HTTP traffic on the first free port it # finds starting at 9200. Set a specific HTTP port here: # #http.port: 9200 # # For more information, consult the network module documentation. # # --------------------------------- Discovery ---------------------------------- # # Pass an initial list of hosts to perform discovery when this node is started: # The default list of hosts is ["127.0.0.1", "[::1]"] # #discovery.seed_hosts: ["host1", "host2"] # # Bootstrap the cluster using an initial set of master-eligible nodes: # #cluster.initial_master_nodes: ["node-1", "node-2"] # # For more information, consult the discovery and cluster formation module documentation. # # --------------------------------- Readiness ---------------------------------- # # Enable an unauthenticated TCP readiness endpoint on localhost # #readiness.port: 9399 # # ---------------------------------- Various ----------------------------------- # # Allow wildcard deletion of indices: # #action.destructive_requires_name: false #----------------------- BEGIN SECURITY AUTO CONFIGURATION ----------------------- # # The following settings, TLS certificates, and keys have been automatically # generated to configure Elasticsearch security features on 16-03-2023 07:16:50 # # -------------------------------------------------------------------------------- # Enable security features xpack.security.enabled: true xpack.security.enrollment.enabled: true # Enable encryption for HTTP API client connections, such as Kibana, Logstash, and Agents xpack.security.http.ssl: enabled: true keystore.path: certs/http.p12 # Enable encryption and mutual authentication between cluster nodes xpack.security.transport.ssl: enabled: true verification_mode: certificate keystore.path: certs/transport.p12 truststore.path: certs/transport.p12 # Create a new cluster with the current node only # Additional nodes can still join the cluster later cluster.initial_master_nodes: ["FM11L"] # Allow HTTP API connections from anywhere # Connections are encrypted and require user authentication http.host: 0.0.0.0 # Allow other nodes to join the cluster from anywhere # Connections are encrypted and mutually authenticated #transport.host: 0.0.0.0 #----------------------- END SECURITY AUTO CONFIGURATION -------------------------
原因分析
你看到的不是"未分配索引",而是索引的副本分片未分配,核心原因是:
- Elasticsearch默认创建索引时,会生成1个主分片+1个副本分片(
number_of_replicas: 1) - 你的集群只有1个节点(从
cluster.initial_master_nodes: ["FM11L"]可以确认是单节点部署),Elasticsearch不允许副本分片和主分片放在同一个节点上(避免单点故障时数据丢失),所以副本分片会一直处于未分配状态
解决办法
有两种方式可以彻底避免这个问题:
创建索引时显式设置副本数为0
修改你的C#代码,在Settings配置中添加副本数设置,这样就不会生成副本分片,自然不会出现未分配的情况:ElasticClient.Indices.Create("1234.attachments", c => c .Settings(s => s .NumberOfReplicas(0) // 新增该行,关闭副本分片 .Analysis(a => a .Analyzers(ad => ad .Custom("windows_path_hierarchy_analyzer", ca => ca .Tokenizer("windows_path_hierarchy_tokenizer") ) ) .Tokenizers(t => t .PathHierarchy("windows_path_hierarchy_tokenizer", ph => ph .Delimiter('\\') ) .NGram("ngram_tokenizer", td => td .MinGram(3) .MaxGram(3) .TokenChars( TokenChar.Letter, TokenChar.Digit, TokenChar.Symbol) ) ) ) ) .Map<ElasticDocument>(mp => mp .AutoMap() .Properties(ps => ps .Text(s => s .Name(n => n.Doname) .Analyzer("windows_path_hierarchy_analyzer") ) .Object<Attachment>(a => a .Name(n => n.Attachment) .AutoMap() ) ) ) );修改全局默认副本数(适合固定单节点场景)
如果你的环境一直是单节点部署,可以在elasticsearch.yml中添加全局配置,让所有新创建的索引默认都不生成副本:index.number_of_replicas: 0修改后需要重启Elasticsearch生效,这种方式会影响所有新创建的索引,谨慎使用。
已创建索引的修复方案
如果已经创建了这个索引,可以通过Kibana执行以下命令修改副本数,快速解决未分配问题:
PUT /1234.attachments/_settings { "number_of_replicas": 0 }
内容的提问来源于stack exchange,提问作者Frank Mehlhop
相关产品推荐
相关产品推荐

