Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZOOKEEPER-2840: Should using System.nanoTime() ^ this.hashCode() for StaticHostProvider #303

Closed
wants to merge 1 commit into from
Closed

Conversation

@asdf2014
Copy link
Member

@asdf2014 asdf2014 commented Jul 5, 2017

Should using System.nanoTime() ^ this.hashCode() for StaticHostProvider instead of System.currentTimeMillis(). Because if we have three Zookeeper server nodes and set the zookeeper.leaderServes as no, then those connections from client will always connect with the first Zookeeper server node. Due to...

    @Test
    public void testShuffle() throws Exception {
        LinkedList<InetSocketAddress> inetSocketAddressesList = new LinkedList<>();
        inetSocketAddressesList.add(new InetSocketAddress(0));
        inetSocketAddressesList.add(new InetSocketAddress(1));
        inetSocketAddressesList.add(new InetSocketAddress(2));
        /*
        1442045361
        currentTime: 1499253530044, currentTime ^ hashCode: 1500143845389, Result: 1 2 0
        currentTime: 1499253530044, currentTime ^ hashCode: 1500143845389, Result: 2 0 1
        currentTime: 1499253530045, currentTime ^ hashCode: 1500143845388, Result: 0 1 2
        currentTime: 1499253530045, currentTime ^ hashCode: 1500143845388, Result: 1 2 0
        currentTime: 1499253530046, currentTime ^ hashCode: 1500143845391, Result: 1 2 0
        currentTime: 1499253530046, currentTime ^ hashCode: 1500143845391, Result: 1 2 0
        currentTime: 1499253530046, currentTime ^ hashCode: 1500143845391, Result: 1 2 0
        currentTime: 1499253530046, currentTime ^ hashCode: 1500143845391, Result: 1 2 0
        currentTime: 1499253530047, currentTime ^ hashCode: 1500143845390, Result: 1 2 0
        currentTime: 1499253530047, currentTime ^ hashCode: 1500143845390, Result: 1 2 0
         */
        internalShuffleMillis(inetSocketAddressesList);
        /*
        146611050
        currentTime: 22618159623770, currentTime ^ hashCode: 22618302559536, Result: 2 1 0
        currentTime: 22618159800738, currentTime ^ hashCode: 22618302085832, Result: 0 1 2
        currentTime: 22618159967442, currentTime ^ hashCode: 22618302248888, Result: 1 0 2
        currentTime: 22618160135080, currentTime ^ hashCode: 22618302013634, Result: 2 1 0
        currentTime: 22618160302095, currentTime ^ hashCode: 22618301535077, Result: 2 1 0
        currentTime: 22618160490260, currentTime ^ hashCode: 22618301725822, Result: 1 0 2
        currentTime: 22618161566373, currentTime ^ hashCode: 22618300303823, Result: 1 0 2
        currentTime: 22618161745518, currentTime ^ hashCode: 22618300355844, Result: 2 1 0
        currentTime: 22618161910357, currentTime ^ hashCode: 22618291603775, Result: 2 1 0
        currentTime: 22618162079549, currentTime ^ hashCode: 22618291387479, Result: 0 1 2
         */
        internalShuffleNano(inetSocketAddressesList);

        inetSocketAddressesList.clear();
        inetSocketAddressesList.add(new InetSocketAddress(0));
        inetSocketAddressesList.add(new InetSocketAddress(1));

        /*
        415138788
        currentTime: 1499253530050, currentTime ^ hashCode: 1499124456998, Result: 0 1
        currentTime: 1499253530050, currentTime ^ hashCode: 1499124456998, Result: 0 1
        currentTime: 1499253530050, currentTime ^ hashCode: 1499124456998, Result: 0 1
        currentTime: 1499253530050, currentTime ^ hashCode: 1499124456998, Result: 0 1
        currentTime: 1499253530050, currentTime ^ hashCode: 1499124456998, Result: 0 1
        currentTime: 1499253530050, currentTime ^ hashCode: 1499124456998, Result: 0 1
        currentTime: 1499253530053, currentTime ^ hashCode: 1499124456993, Result: 0 1
        currentTime: 1499253530055, currentTime ^ hashCode: 1499124456995, Result: 0 1
        currentTime: 1499253530055, currentTime ^ hashCode: 1499124456995, Result: 0 1
        currentTime: 1499253530055, currentTime ^ hashCode: 1499124456995, Result: 0 1
         */
        internalShuffleMillis(inetSocketAddressesList);
        /*
        13326370
        currentTime: 22618168292396, currentTime ^ hashCode: 22618156149774, Result: 1 0
        currentTime: 22618168416181, currentTime ^ hashCode: 22618156535703, Result: 1 0
        currentTime: 22618168534056, currentTime ^ hashCode: 22618156432394, Result: 0 1
        currentTime: 22618168666548, currentTime ^ hashCode: 22618155774358, Result: 0 1
        currentTime: 22618168818946, currentTime ^ hashCode: 22618155623712, Result: 0 1
        currentTime: 22618168936821, currentTime ^ hashCode: 22618156011863, Result: 1 0
        currentTime: 22618169056251, currentTime ^ hashCode: 22618155893721, Result: 1 0
        currentTime: 22618169611103, currentTime ^ hashCode: 22618157370237, Result: 1 0
        currentTime: 22618169744528, currentTime ^ hashCode: 22618156713138, Result: 1 0
        currentTime: 22618171273170, currentTime ^ hashCode: 22618184562672, Result: 1 0
         */
        internalShuffleNano(inetSocketAddressesList);
    }

    private void internalShuffleMillis(LinkedList<InetSocketAddress> inetSocketAddressesList) throws Exception {
        int hashCode = new StaticHostProvider(inetSocketAddressesList).hashCode();
        System.out.println(hashCode);
        int count = 10;
        Random r;
        while (count > 0) {
            long currentTime = System.currentTimeMillis();
            r = new Random(currentTime ^ hashCode);
            System.out.print(String.format("currentTime: %s, currentTime ^ hashCode: %s, Result: ",
                    currentTime, currentTime ^ hashCode));
            Collections.shuffle(inetSocketAddressesList, r);
            for (InetSocketAddress inetSocketAddress : inetSocketAddressesList) {
                System.out.print(String.format("%s ", inetSocketAddress.getPort()));
            }
            System.out.println();
            count--;
        }
    }

    private void internalShuffleNano(LinkedList<InetSocketAddress> inetSocketAddressesList) throws Exception {
        int hashCode = new StaticHostProvider(inetSocketAddressesList).hashCode();
        System.out.println(hashCode);
        int count = 10;
        Random r;
        while (count > 0) {
            long currentTime = System.nanoTime();
            r = new Random(currentTime ^ hashCode);
            System.out.print(String.format("currentTime: %s, currentTime ^ hashCode: %s, Result: ",
                    currentTime, currentTime ^ hashCode));
            Collections.shuffle(inetSocketAddressesList, r);
            for (InetSocketAddress inetSocketAddress : inetSocketAddressesList) {
                System.out.print(String.format("%s ", inetSocketAddress.getPort()));
            }
            System.out.println();
            count--;
        }
    }
@asdf2014 asdf2014 changed the title ZOOKEEPER-2840: Should using System.nanoTime() ^ this.hashCode() fo… ZOOKEEPER-2840: Should using System.nanoTime() ^ this.hashCode() for StaticHostProvider Jul 6, 2017
@@ -71,7 +71,7 @@
* if serverAddresses is empty or resolves to an empty list
*/
public StaticHostProvider(Collection<InetSocketAddress> serverAddresses) {
sourceOfRandomness = new Random(System.currentTimeMillis() ^ this.hashCode());
sourceOfRandomness = new Random(System.nanoTime() ^ this.hashCode());
Copy link
Member

@maoling maoling Aug 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asdf2014

  • shift right a space(haha,original code is also not alignment)
  • according to ZOOKEEPER-1990

    the goal here is to make sure that when multiple client threads start at the same time on the same machine
    (such as in our systest) and execute this line each one is likely to have a different random seed.

  • your demo is not convincing because different client have different values of this.hashCode()(different instances) although the elements in inetSocketAddressesList is same. Look at my demo

Loading

Copy link
Member Author

@asdf2014 asdf2014 Apr 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, @maoling. Sorry for my belated comment. Indeed, i hadn't been considered this case that different clients will own different hashcodes. Because, in my sistuation, our Zookeeper clusters only give service to some apointed BigData components, e.g., HBase, Druid.io, Hadoop, Kafka etc. Inside these components will have settled clients, so them can not offer too many different hashcodes.

Loading

@anmolnar
Copy link
Contributor

@anmolnar anmolnar commented Mar 31, 2020

Closing this one due to long inactivity.

Loading

@anmolnar anmolnar closed this Mar 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants