读写侧容错
SolrCloud 支持伸缩性,高可用和读写容错。这意味着,如果你有个大的集群,总是可以发送请求到集群:只要有可能,读请求总是能返回结果,即使某些节点宕机;写请求将收到回执。你不会丢失数据
读容错
SolrCloud 集群里,读请求是集合里的节点来均衡负载的。你仍然需要一个外部的负载均衡器来,或者一个智能客户端,能明白如何读 ZooKeeper 里的元数据来发现应向哪个节点发送请求。
Solr 提供了一个 Java 的客户端 CloudSolrClient
zkConnected
一个 Solr 节点会在它能联系到每个分片的至少一个副本时返回查询结果,甚至是在它收到请求时无法联系到 ZooKeeper。为了容错这通常是优先的做法,但是可能会得到错误的结果或者脏数据,如果整个集合的结构发生了大的变化而该节点还没有能从 ZooKeeper 得到通知。例如,新增或移除了分片,或者某个分片切分成子分片
每个查询结果都包含一个 zkConnected
头来指示节点是否在处理请求时连接到 ZooKeeper
{
"responseHeader": {
"status": 0,
"zkConnected": true,
"QTime": 20,
"params": {
"q": "*:*"
}
},
"response": {
"numFound": 107,
"start": 0,
"docs": [ ... ]
}
}
shards.tolerant
如果一个或多个分片不可用,Solr 默认的行为是请求失败。但是,很多场景部分结果是可接受的,所以 Solr 提供一个逻辑参数 shards.tolerant
(默认false
)。如果 shards.tolerant=true
,会返回部分结果。如果返回的结果不包含所有分片,返回头里有一个特殊的标识 partialResults
。客户端可以同时指定 shards.info
参数来获取更多的细节
{
"responseHeader": {
"status": 0,
"zkConnected": true,
"partialResults": true,
"QTime": 20,
"params": {
"q": "*:*"
}
},
"response": {
"numFound": 77,
"start": 0,
"docs": [ ... ]
}
}
写容错
SolrCloud 被设计为复制文档来确保数据的冗余,并允许发送更新请求到集群内任何节点。节点会判断它是否承载了分片的领导(leader),如果没有的话会转发请求给领导(leader),领导会转发请求到所有存在的副本,使用版本控制来确保所有副本都有最新的版本。如果领导(leader)宕机,某个其他副本会取代它。这个架构保证你的数据能在灾难时恢复,即使你在使用近实时搜索。
Recovery
每个节点都有一个事务日志,每一次对内容或组织的修改都会被记录。这个日志被用来判断节点的哪些内容应该包含到副本。当一个新副本被创建,它会引用领导(leader)和事务日志来明白要包含哪些内容。如果失败的话会重试。
事务日志是由更新记录组成,提供了索引的健壮性,如果索引被中断,它可以重做未提交的索引
如果领导(leader)宕机,它可能已发送了请求到某些副本而未发送给其他副本。当一个新的领导(leader)选出,会运行一个同步进程,同步其他副本数据。如果运行成功,所有都会一致,领导(leader)注册为活跃的,如果一个副本无法同步,系统会要求一次全量复制
核在重新加载 schema,某些成功了,另一些还没有成功,会导致一个更新失败,领导(leader)将告诉节点并启动一个恢复过程
Achieved Replication Factor
当使用一个大于 1 的复制因子,一个更新请求可能在分片领导(leader)上成功而在一个或多个副本上失败。例如,一个集合有 1 个分片,复制因子为 3,这样你就有 1 个分片领导(leader)和 2 个额外的副本,如果一个更新请求在领导(leader)上成功,但是在副本上都失败,不论是因为什么原因,这个更新请求在客户端看来是成功的。副本恢复后会从领导(leader)同步错过的数据。
在幕后,这表明 Solr 仅在一个节点上(这里是领导(leader))进行了更新。Solr 在更新时,支持可选的参数 min_rf
,使服务器返回成功复制因子。上例中,如果客户端包含了 min_rf >= 1
,Solr 将在结果的头信息里返回 rf=1
,因为只有领导(leader)更新成功。min_rf
参数并不强制 Solr 必须最少在几个副本上更新,因为 Solr 并不支持在更新成功的副本上回滚。这个参数仅表示客户端希望知道更新请求的成功复制因子是什么。
在客户端,如果成功复制因子小于可接受的水平,可以为这个降级的状态做一个额外的评估。例如,客户端可以记录日志,当集合降级时,哪些更新请求被发送,在问题解决后重新发送这些更新请求。简而言之,min_rf
是集合处于一种降级状态时,对于更新请求返回给客户端的一种可选的警告机制