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

chore: LockTable tracks fingerprints of keys #2839

Merged
merged 3 commits into from
Apr 10, 2024
Merged

chore: LockTable tracks fingerprints of keys #2839

merged 3 commits into from
Apr 10, 2024

Conversation

romange
Copy link
Collaborator

@romange romange commented Apr 4, 2024

It's a first step that will probably simplify dependencies in many places where we need to keep key strings for that. A second step will be to reduce the CPU load of multi-key operations like MSET and precompute Fingerprints once.

Comment on lines 104 to 109
// We use fingerprinting before accessing locks - no need to mix more.
struct Hasher {
size_t operator()(uint64_t val) const {
return val;
}

// If the key is backed by a string_view, replace it with a string with the same value
void MakeOwned() const;

mutable std::variant<std::string_view, std::string> val_;
};

absl::flat_hash_map<Key, IntentLock> locks_;
absl::flat_hash_map<uint64_t, IntentLock, Hasher> locks_;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we need a custom hasher instead of just absl::flat_hash_map<uint64_t, IntentLock>?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

line 104 explains. If it's not clear I will expand there.

src/server/table.h Outdated Show resolved Hide resolved
src/server/transaction.h Outdated Show resolved Hide resolved
Copy link
Contributor

@dranikpg dranikpg left a comment

Choose a reason for hiding this comment

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

Please share benchmark results. I like that we remove code, but I doubt it's faster, we just moved the hashing part to our side

src/server/table.h Outdated Show resolved Hide resolved
@romange
Copy link
Collaborator Author

romange commented Apr 4, 2024

Please share benchmark results. I like that we remove code, but I doubt it's faster, we just moved the hashing part to our side

Exactly right. Because it's a half-work. Doing the second half :)

@romange
Copy link
Collaborator Author

romange commented Apr 4, 2024

Ok, I implemented Release/Acquire with fingerprints. the performance difference is negligible for MSET.
@dranikpg I am fine to sack this PR but I think it will simplify things for multi transactions as well.
See the second half here: https://github.com/dragonflydb/dragonfly/compare/Pr6?expand=1

@romange romange requested a review from dranikpg April 4, 2024 14:02
Copy link
Contributor

@dranikpg dranikpg left a comment

Choose a reason for hiding this comment

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

Okay, so given it doesn't have much of performance advantages

  1. I'm not opposed to the idea if it simplifies code. However, in many cases we need to now keep track of both string and fingerprints, not sure if it's a simplification on average over the long run.
  2. I still don't understand why you insist on making CheckLock a member function on transaction. It never belonged there, especially as a member. We spent so much effort previously to remove all excessive code from it 😿

@romange
Copy link
Collaborator Author

romange commented Apr 5, 2024

(2) is not important. And I do not insist on this. it's just is currently used only there but we can move it back to DbSlice.
I agree that we need to keep both fps and keys because we need to know which keys belong to which shards.

dranikpg
dranikpg previously approved these changes Apr 5, 2024
Copy link
Contributor

@dranikpg dranikpg left a comment

Choose a reason for hiding this comment

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

You can move (2) to anonymous namespace. I'm being annoyingly picky because of https://en.wikipedia.org/wiki/Broken_windows_theory. First glass shattering 😆

(1) Is up to you. I don't have strong opinions as long as it's maintainable

@romange
Copy link
Collaborator Author

romange commented Apr 10, 2024

I decided to proceed with this PR. I believe this PR will help me to implement more advanced heuristics of VLL paper, where we can identify OOO Transactions in the TX queue even before they reach the TX-queue head. Not something we must do urgently but I think it does simplify things with everything related to key locking.

@romange romange requested review from chakaz and dranikpg April 10, 2024 08:09
", contended locks: ", info.contended_locks, "\n");
string msg = StrCat("TxQueue is too long. Tx count:", info.tx_total,
", armed:", info.tx_armed, ", runnable:", info.tx_runnable,
", global:", info.tx_global, ", total locks: ", info.total_locks,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

just added global stats

It's a first step that will probably simplify dependencies in many places
where we need to keep key strings for that. A second step will be to reduce the CPU load
of multi-key operations like MSET and precompute Fingerprints once.

Signed-off-by: Roman Gershman <roman@dragonflydb.io>
chakaz
chakaz previously approved these changes Apr 10, 2024
Comment on lines 89 to 90
bool Acquire(std::string_view key, IntentLock::Mode mode);
void Release(std::string_view key, IntentLock::Mode mode);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Here's a proposal: have overloads for both of these functions, the existing one (accepting a string_view), and another one accepting a fingerprint.
Then have the string_view version do the hash and call the overloaded one. This will save you the trouble of adding them in the future PR you plan to add.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I already wrote this in another branch. I prefer adding them in the next PR but I did like you suggested.

@@ -92,17 +89,24 @@ class LockTable {
bool Acquire(std::string_view key, IntentLock::Mode mode);
void Release(std::string_view key, IntentLock::Mode mode);

static uint64_t Fingerprint(std::string_view key);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Consider some typedef for the fingerprint type, like using THash = uint64_t

Copy link
Contributor

@dranikpg dranikpg Apr 10, 2024

Choose a reason for hiding this comment

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

It won't grow, it won't shrink, keeps less types. std::hash uses size_t as well after all

Copy link
Collaborator

Choose a reason for hiding this comment

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

giving a name to this "type" makes the code easier to read (like that it's not an index but a hash). once C++ will get distinct typedef it'll be even better, because then the compiler can guard against such errors

chakaz
chakaz previously approved these changes Apr 10, 2024
@romange romange merged commit da5c51d into main Apr 10, 2024
10 checks passed
@romange romange deleted the Pr5 branch April 10, 2024 14:52
szinn pushed a commit to szinn/k8s-homelab that referenced this pull request Apr 16, 2024
…nfly ( v1.16.1 → v1.17.0 ) (#3473)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
|
[docker.dragonflydb.io/dragonflydb/dragonfly](https://togithub.com/dragonflydb/dragonfly)
| minor | `v1.16.1` -> `v1.17.0` |

---

### Release Notes

<details>
<summary>dragonflydb/dragonfly
(docker.dragonflydb.io/dragonflydb/dragonfly)</summary>

###
[`v1.17.0`](https://togithub.com/dragonflydb/dragonfly/releases/tag/v1.17.0)

[Compare
Source](https://togithub.com/dragonflydb/dragonfly/compare/v1.16.1...v1.17.0)

##### Dragonfly v1.17.0

Some prominent changes include:

- Improved performance for MGET operations
([#&#8203;2453](https://togithub.com/dragonflydb/dragonfly/issues/2453))
- Fix argument parsing in json.objkeys
([#&#8203;2872](https://togithub.com/dragonflydb/dragonfly/issues/2872))
- Fix ipv6 support for replication
([#&#8203;2889](https://togithub.com/dragonflydb/dragonfly/issues/2889))
- Support serialisation of bloom filters - saving to and loading from
snapshots
([#&#8203;2846](https://togithub.com/dragonflydb/dragonfly/issues/2846))
- Support of HLL PFADD
([#&#8203;2761](https://togithub.com/dragonflydb/dragonfly/issues/2761))
- Support bullmq workloads that do not have `{}` hashtags in their queue
names
([#&#8203;2890](https://togithub.com/dragonflydb/dragonfly/issues/2890))

##### What's Changed

- fix:
[#&#8203;2745](https://togithub.com/dragonflydb/dragonfly/issues/2745)
don't start migration process again after apply the same the same config
is applied by [@&#8203;BorysTheDev](https://togithub.com/BorysTheDev) in
[dragonflydb/dragonfly#2822
- feat(transaction): Idempotent callbacks (immediate runs) by
[@&#8203;dranikpg](https://togithub.com/dranikpg) in
[dragonflydb/dragonfly#2453
- refactor(cluster): replace sync_id with node_id for slot migration
[#&#8203;2835](https://togithub.com/dragonflydb/dragonfly/issues/2835)
by [@&#8203;BorysTheDev](https://togithub.com/BorysTheDev) in
[dragonflydb/dragonfly#2838
- feat(tiering): Simple OpManager by
[@&#8203;dranikpg](https://togithub.com/dranikpg) in
[dragonflydb/dragonfly#2781
- chore: implement path mutation for JsonFlat by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2805
- feat(cluster): add migration removing by config
[#&#8203;2835](https://togithub.com/dragonflydb/dragonfly/issues/2835)
by [@&#8203;BorysTheDev](https://togithub.com/BorysTheDev) in
[dragonflydb/dragonfly#2844
- chore: expose direct API on Bloom objects by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2845
- chore: generalize CompactObject::AllocateMR by
[@&#8203;kostasrim](https://togithub.com/kostasrim) in
[dragonflydb/dragonfly#2847
- feat(tiering): Simplest small bins by
[@&#8203;dranikpg](https://togithub.com/dranikpg) in
[dragonflydb/dragonfly#2810
- refactor: clean cluster slot migration code by
[@&#8203;BorysTheDev](https://togithub.com/BorysTheDev) in
[dragonflydb/dragonfly#2848
- fix(tests): Fix numsub test by
[@&#8203;dranikpg](https://togithub.com/dranikpg) in
[dragonflydb/dragonfly#2852
- fix: healthcheck for docker containers by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2853
- fix: possible crash in tls code by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2854
- fix(server): Do not block admin-port commands by
[@&#8203;chakaz](https://togithub.com/chakaz) in
[dragonflydb/dragonfly#2842
- fix(pytest): make pytests fail if server crash on shutdown by
[@&#8203;adiholden](https://togithub.com/adiholden) in
[dragonflydb/dragonfly#2827
- feat(server): add prints on takeover timeout by
[@&#8203;adiholden](https://togithub.com/adiholden) in
[dragonflydb/dragonfly#2856
- fix(pytest): dont check process return code on kill by
[@&#8203;adiholden](https://togithub.com/adiholden) in
[dragonflydb/dragonfly#2862
- fix: authorize the http connection to call commands by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2863
- feat(cluster): Send number of keys for incoming and outgoing
migrations. by [@&#8203;chakaz](https://togithub.com/chakaz) in
[dragonflydb/dragonfly#2858
- feat(tiering): TieredStorageV2 by
[@&#8203;dranikpg](https://togithub.com/dranikpg) in
[dragonflydb/dragonfly#2849
- bug(server): set connection flags block/pause flag on all blocking
commands by [@&#8203;adiholden](https://togithub.com/adiholden) in
[dragonflydb/dragonfly#2816
- chore: serialize SBF by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2846
- fix: test_replicaof_reject_on_load crash on stop by
[@&#8203;kostasrim](https://togithub.com/kostasrim) in
[dragonflydb/dragonfly#2818
- feat(dbslice): Add self-laundering iterator in `DbSlice` by
[@&#8203;chakaz](https://togithub.com/chakaz) in
[dragonflydb/dragonfly#2815
- chore: License update by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2767
- fix(acl): incompatibilities with acl load by
[@&#8203;kostasrim](https://togithub.com/kostasrim) in
[dragonflydb/dragonfly#2867
- fix(json): make path optional in json.objkeys by
[@&#8203;kostasrim](https://togithub.com/kostasrim) in
[dragonflydb/dragonfly#2872
- fix: return wrong type errors for SET...GET command by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2874
- fix(redis replication): remove partial sync flow ,not supported yet by
[@&#8203;adiholden](https://togithub.com/adiholden) in
[dragonflydb/dragonfly#2865
- chore: limit traffic logger only to the main interface by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2877
- chore: relax repltakeover constraints to only exclude write commands
by [@&#8203;kostasrim](https://togithub.com/kostasrim) in
[dragonflydb/dragonfly#2873
- chore(replayer): Roll back to go1.18 by
[@&#8203;dranikpg](https://togithub.com/dranikpg) in
[dragonflydb/dragonfly#2881
- fix: brpoplpush single shard to wake up blocked transactions by
[@&#8203;kostasrim](https://togithub.com/kostasrim) in
[dragonflydb/dragonfly#2875
- chore: LockTable tracks fingerprints of keys by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2839
- chore: reject TLS handshake when our listener is plain TCP by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2882
- Add support for Sparse HLL PFADD by
[@&#8203;azuredream](https://togithub.com/azuredream) in
[dragonflydb/dragonfly#2761
- feat server: bring visibility to script errors by
[@&#8203;adiholden](https://togithub.com/adiholden) in
[dragonflydb/dragonfly#2879
- chore: clean up REPLTAKEOVER flow by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2887
- chore(tiering): Move files and move kb literal to common by
[@&#8203;dranikpg](https://togithub.com/dranikpg) in
[dragonflydb/dragonfly#2868
- chore(interpreter): Support object replies by
[@&#8203;dranikpg](https://togithub.com/dranikpg) in
[dragonflydb/dragonfly#2885
- fix(ci/helm): Stick to v0.73.0 version of prom operator by
[@&#8203;Pothulapati](https://togithub.com/Pothulapati) in
[dragonflydb/dragonfly#2893
- fix(acl): authentication with UDS socket by
[@&#8203;kostasrim](https://togithub.com/kostasrim) in
[dragonflydb/dragonfly#2895
- feat(cluster): add repeated ACK if an error is happened by
[@&#8203;BorysTheDev](https://togithub.com/BorysTheDev) in
[dragonflydb/dragonfly#2892
- chore(blocking): Remove faulty DCHECK by
[@&#8203;dranikpg](https://togithub.com/dranikpg) in
[dragonflydb/dragonfly#2898
- chore: add a clear link on how to build dragonfly from source by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2884
- feat(server): Allow configuration of hashtag extraction by
[@&#8203;chakaz](https://togithub.com/chakaz) in
[dragonflydb/dragonfly#2890
- fix: fix build under macos by
[@&#8203;BorysTheDev](https://togithub.com/BorysTheDev) in
[dragonflydb/dragonfly#2901
- fix(cluster_replication): replicate redis cluster node bug fix by
[@&#8203;adiholden](https://togithub.com/adiholden) in
[dragonflydb/dragonfly#2876
- fix(acl): skip http and add check on connection traversals by
[@&#8203;kostasrim](https://togithub.com/kostasrim) in
[dragonflydb/dragonfly#2883
- fix(zset): Better memory consumption calculation by
[@&#8203;chakaz](https://togithub.com/chakaz) in
[dragonflydb/dragonfly#2900
- fix: fix ld for num converting by
[@&#8203;BorysTheDev](https://togithub.com/BorysTheDev) in
[dragonflydb/dragonfly#2902
- chore: add help string for memory_fiberstack_vms_bytes by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2903
- fix(sanitizers): false positive fail on multi_test::Eval by
[@&#8203;kostasrim](https://togithub.com/kostasrim) in
[dragonflydb/dragonfly#2896
- chore: pull helio and add ipv6 replication test by
[@&#8203;dranikpg](https://togithub.com/dranikpg) in
[dragonflydb/dragonfly#2889
- chore: add ipv6 support for native linux release by
[@&#8203;romange](https://togithub.com/romange) in
[dragonflydb/dragonfly#2908

##### Huge thanks to all the contributors! ❤️

**Full Changelog**:
dragonflydb/dragonfly@v1.16.0...v1.17.0

</details>

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zMDEuNSIsInVwZGF0ZWRJblZlciI6IjM3LjMwMS41IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19-->

Co-authored-by: repo-jeeves[bot] <106431701+repo-jeeves[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants