SOLR-18094 Support running embedded-zk in "ensemble" mode with new node role#2391
SOLR-18094 Support running embedded-zk in "ensemble" mode with new node role#2391gerlowskija wants to merge 60 commits into
Conversation
…found" with an out-dated ClusterState (apache#2363)" This reverts commit 5c399dd.
This commit augments our embedded-ZK code to support running embedded-ZK
in "quorum" or ensemble mode. Multiple Solr nodes can now all have
their embedded-ZK's join a multi-node quorum upon startup. Other than
Solr and ZK sharing a process, the embedded- ZK ensemble behaves
identically to one formed of independent processes: nodes can join or
leave the cluster, etc.
Embedded-ensemble-ZK is enabled any time the `zkQuorumRun` system
property is present, along with an explicitly specified ZK host string.
On startup, Solr will identify which host in the zk-conn-string it
should be (based on admittedly hacky heuristics), and then spins up a
'ZooKeeperServerEmbedded' instance in-process to join the ensemble. e.g.
```
export LH="localhost"
bin/solr start -p 8983 -z $LH:9983,$LH:9984,$LH:9985 -DzkQuorumRun
bin/solr start -p 8984 -z $LH:9983,$LH:9984,$LH:9985 -DzkQuorumRun
bin/solr start -p 8985 -z $LH:9983,$LH:9984,$LH:9985 -DzkQuorumRun
```
Some notes:
- this doesn't (yet) work with ZK's dynamic-ensemble feature, so all
ZK nodes must be specified in a static ZK conn string provided at
startup
- this appears to run best when the security-manager is disabled.
|
FYI: https://cwiki.apache.org/confluence/display/SOLR/SIP-14+Embedded+Zookeeper for context on others' interest in moving this direction. |
|
Great work. I think we should rip out the existing embedded ZK, which is a hack. Do you want to proceed in a PR or perhaps in a central feature branch? |
…ion not found" with an out-dated ClusterState (apache#2363)"" This reverts commit 1fb376b.
88c8da4 to
de59401
Compare
|
Spent a few minutes pulling in the latest 'main'. Hoping to give it a bit more cleanup in the next few days if I can, but I've been hoping that for more than a year at this point (😬 ), so if anyone else is interested please feel free to move this forward! |
|
@gerlowskija I took a stab at getting in the use of the solr roles to determine if we hsould run embedded zk quorum mode, and it worked! Here is my start script, where each runs with |
# Conflicts: # solr/core/src/java/org/apache/solr/core/ZkContainer.java # solr/packaging/build.gradle
|
|
FYI, the |
Uses a base class SolrCloudWithEmbeddedZkQuorumTestCase New MiniSolrCloudCluster constructor that spins up a quorum cluster
…aging/build.gradle
… avoid disk roundtrip
Single-machine example with consecutive Solr ports 8983/8984/8985 caused ZK quorum/election port collisions (node N's quorum port = node N+1's client port). Fix by separating the multi-machine and single-machine examples, and using ports spaced ≥3 apart (8983, 8986, 8989) for the single-machine case.
|
|
||
| bin/solr start -p 20000 $ZK $ROLES | ||
| bin/solr start -p 30000 $ZK $ROLES | ||
| bin/solr start -p 40000 $ZK $ROLES |
There was a problem hiding this comment.
Running three nodes like this causes all three embedded zookeepers to use exact same server/solr/zoo_home/data folder, which is not good of course.
There was a problem hiding this comment.
I fixed it it commit ccf6ec3 - appending -<port> to the zoo_home folder name.
There was a problem hiding this comment.
so, we can't do 8983, 8984,8985? That is definitly a conceptual change for all of us. I'm used to zk being 1000 more that my port...
|
|
||
| |ZK leader election | ||
| |`zk_client_port + 2` | ||
| |9985 |
There was a problem hiding this comment.
I modified the default ports used for quorum peer and leader election ports. They were something like client-port minus 3000 and minus 4000. Now they are +1 and +2. I feel we spread our port numbers too wide. But then after the change we got another problem that we could not start three test solr nodes on 8983, 8984, 8985, since the first one would occupy port 9983, 9984, 9985 for zookeeper.
I am willing to revert the +1, +2 to something else, but -3000 and -4000 seemed a bit arbitrary, why not +2000 and +3000 since client-port is +1000?
There was a problem hiding this comment.
Yeah, after commenting elsewhere, I like your +2000 and +3000 idea.
There was a problem hiding this comment.
I’d prefer if Solr occupied a more narrow port space, say within 100 ports total, so you could start Solr on 8000, 8100, 8200 and each instance would have ports close. Instead of node 1 using 8000, 9000, 10000, 11000, while node 2 using 8100, 9100, 10100, 11100….
There was a problem hiding this comment.
And come to think of it, each and every of these ports should probably be configurable individually even if they default to some port offset...
| final Path zkDataHome = | ||
| Path.of( | ||
| EnvUtils.getProperty( | ||
| "solr.zookeeper.server.datadir", solrHome.resolve("zoo_data").toString())); |
There was a problem hiding this comment.
Do we normally keep constants like this inline or do we have somewhere we try to keep all sysprop-names for e.g. zookeeper together in one place?



Description
Prior to this commit, Solr only supported running embedded-ZK in "standalone" mode (which cannot take part in any larger ZK ensemble or quorum). But there are usecases that would benefit from being able to do this, both on the development and testing side, and even for adventurous users who might want the benefits of a small multi-node SolrCloud cluster without the headache of also deploying ZK.
See SIP-14, SOLR-15636 for context.
Solution
This commit augments the embedded-ZK code to support running in "quorum" or ensemble mode. Multiple Solr nodes can now all have their embedded ZK join a multi-node quorum upon startup. Other than Solr and ZK sharing a process, the embedded-ZK ensemble behaves identically to one formed of independent processes.
Embedded-ensemble-ZK is enabled by assigning the new
zookeeper_quorumnode role (on/off) via thesolr.node.rolessystem property, along with an explicit ZK host string containing all quorum members. Solr identifies which host in the ZK connection string it should be (based on host/port matching) and starts aZooKeeperServerEmbeddedinstance in-process to join the ensemble. For example:Known limitations (Phase 1 / experimental):
testQuorumLossAndRecoverymarked@AwaitsFix).solr.host).Tests
TestEmbeddedZkQuorum— basic quorum startup, collection creation, and node join/leave scenariosChecklist
Please review the following and check all that apply:
mainbranch../gradlew check.