Skip to content
This repository has been archived by the owner on Feb 27, 2023. It is now read-only.

add hash circler locator #1362

Merged

Conversation

wangforthinker
Copy link
Contributor

@wangforthinker wangforthinker commented May 27, 2020

Signed-off-by: allen.wq [email protected]

Ⅰ. Describe what this PR did

Add an implementation of SuperNodeLocator. HashCirclerLocator allow Add/Delete supernode, and the deleted supernode will not be selected.

Ⅱ. Does this pull request fix one issue?

NONE.

Ⅲ. Why don't you add test cases (unit test/integration test)? (你真的觉得不需要加测试吗?)

add ut.

Ⅳ. Describe how to verify it

Ⅴ. Special notes for reviews

@wangforthinker wangforthinker force-pushed the feat/add-hash-circler-supernode-locator branch from 61dba9d to 5f84bcc Compare May 27, 2020 06:58
@codecov-commenter
Copy link

codecov-commenter commented May 27, 2020

Codecov Report

Merging #1362 into master will increase coverage by 0.56%.
The diff coverage is 82.38%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1362      +/-   ##
==========================================
+ Coverage   51.46%   52.02%   +0.56%     
==========================================
  Files         133      135       +2     
  Lines        8744     8903     +159     
==========================================
+ Hits         4500     4632     +132     
- Misses       3866     3888      +22     
- Partials      378      383       +5     
Impacted Files Coverage Δ
dfget/locator/hashcircler_locator.go 71.25% <71.25%> (ø)
pkg/hashcircler/hash_circler.go 92.53% <92.53%> (ø)
pkg/algorithm/algorithm.go 84.74% <100.00%> (+3.89%) ⬆️
supernode/daemon/mgr/scheduler/manager.go 22.60% <0.00%> (+0.68%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3945cdb...0fdd9e7. Read the comment docs.

Copy link
Member

@lowzj lowzj left a comment

Choose a reason for hiding this comment

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

Why don't use a consistent hash and separate a node into multi discontinuous virtual nodes to implement it instead of the pkg/hashcircler.
The current implementation schedules all the keys which on a node(A) into its previous node(B) when the node(A) is disabled. It means that the previous node(B) will immediately double the pressure.

default:
}

ev, ok := h.evQueue.PollTimeout(time.Second)
Copy link
Member

Choose a reason for hiding this comment

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

It can be written:

if ev, ok := h.evQueue.PollTimeout(time.Second); ok {
	h.handleEvent(ev.(*SuperNodeEvent))
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

}

func (h *hashCirclerLocator) handleEvent(ev *SuperNodeEvent) {
if ev.evType == enableEv {
Copy link
Member

Choose a reason for hiding this comment

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

How about using switch...case... instead of if?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.


// DedupStringArr removes duplicate string in array.
func DedupStringArr(input []string) []string {
dedupMap := make(map[string]struct{})
Copy link
Member

Choose a reason for hiding this comment

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

Another implementation can return a sorted and deduplicated result:

// out is copied from input
sort.Strings(out)
idx := 0
for i := 1; i < len(out); i++ {
    if out[idx] != out[i] {
        idx++
        out[idx] = out[i]
    }
}
return out[:idx+1]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

}

if len(PreSetKeys) == 0 {
return nil, fmt.Errorf("taraget arr is nil")
Copy link
Member

Choose a reason for hiding this comment

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

just log "empty preSetKeys" or "preSetKeys is nil"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.


// NewPreSetHashCircler constructs an instance of preSetHashCircler from presetKeys. And this is thread safety.
// if hashFunc is nil, it will be set to default hash func.
func NewPreSetHashCircler(PreSetKeys []string, hashFunc func(string) uint64) (HashCircler, error) {
Copy link
Member

Choose a reason for hiding this comment

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

s/PreSetKeys/preSetKeys

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.


hashIndex := h.hashFunc(input)
rangeIndex := sort.Search(len(h.circleArr), func(i int) bool {
if hashIndex <= h.circleArr[i].end {
Copy link
Member

Choose a reason for hiding this comment

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

func(i int) bool {
    return hashIndex <= h.circleArr[i].end
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

@wangforthinker wangforthinker force-pushed the feat/add-hash-circler-supernode-locator branch 2 times, most recently from e26d62b to 2d819ea Compare May 29, 2020 03:46
@wangforthinker
Copy link
Contributor Author

Why don't use a consistent hash and separate a node into multi discontinuous virtual nodes to implement it instead of the pkg/hashcircler.
The current implementation schedules all the keys which on a node(A) into its previous node(B) when the node(A) is disabled. It means that the previous node(B) will immediately double the pressure.

Do an Implementation by consistent hasher now.

@wangforthinker wangforthinker force-pushed the feat/add-hash-circler-supernode-locator branch 2 times, most recently from 6e795c6 to 0c5a6e9 Compare May 29, 2020 04:03
break
}

v := rand.Uint64()
Copy link
Member

Choose a reason for hiding this comment

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

It's not a good solution to use rand.Unit64() with a rand.Seed(time.Now().UnixNano()) directly to create virtual nodes, it may cause 2 problems:

  1. it gets different results in different nodes and each execution, this is unexpected
  2. it cannot guarantee that the virtual nodes are evenly distributed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now [0, math.MaxUint64] is spilt into pieces, and range pieces will be evenly distributed by keys.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Once keys are determined, the owners which the divided range belong to are determined again.

@wangforthinker wangforthinker force-pushed the feat/add-hash-circler-supernode-locator branch from 0c5a6e9 to 7c081f9 Compare June 1, 2020 03:22
@wangforthinker wangforthinker force-pushed the feat/add-hash-circler-supernode-locator branch from 7c081f9 to 0da63b0 Compare June 2, 2020 09:34
@wangforthinker
Copy link
Contributor Author

Now Consistent hash circler has been implemented for HashCircler, Could you have a review
on this? ping @lowzj

@wangforthinker
Copy link
Contributor Author

optimize the hash circle, the algorithm of insert/delete/find is updated to rbtree instead of array.
@lowzj PTAL.

…ted to rbtree instead of array.

Signed-off-by: allen.wq <[email protected]>
@wangforthinker wangforthinker force-pushed the feat/add-hash-circler-supernode-locator branch from 0963638 to 0fdd9e7 Compare June 8, 2020 03:57
Copy link
Member

@lowzj lowzj left a comment

Choose a reason for hiding this comment

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

LGTM

@lowzj lowzj merged commit 80eae52 into dragonflyoss:master Jun 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants