Skip to content

Add Jedis (for Valkey) caches for domains and hosts - #3013

Merged
gbrodman merged 1 commit into
google:masterfrom
gbrodman:jedis
Apr 24, 2026
Merged

Add Jedis (for Valkey) caches for domains and hosts#3013
gbrodman merged 1 commit into
google:masterfrom
gbrodman:jedis

Conversation

@gbrodman

@gbrodman gbrodman commented Apr 16, 2026

Copy link
Copy Markdown
Collaborator

We add optional Valkey caching of hosts and domains for future use. Eventually, this will allow us to pre-warm large amounts of data in Valkey for quick retrieval during actions like RDAP.

Note: this doesn't actually use the caches yet.

We use Jedis instead of Redisson for speed purposes
(https://www.instaclustr.com/blog/redis-java-clients-and-client-side-caching/)
which means that we have to implement our own multilayer cache but
that's not the worst thing in the world.

Tested on crash with logging and RDAP code that's not included in this
PR -- it behaves as you'd expect, where the local cache works for
immediate re-lookups and the remote cache works after a restart.


This change is Reviewable

@gbrodman
gbrodman force-pushed the jedis branch 5 times, most recently from ffce812 to 2198f73 Compare April 17, 2026 14:49
Comment thread core/src/main/java/google/registry/cache/CacheModule.java Fixed
@gbrodman
gbrodman force-pushed the jedis branch 2 times, most recently from cfced4c to 37c8675 Compare April 17, 2026 22:11
Comment thread core/src/main/java/google/registry/model/common/TimeOfYear.java Fixed
Comment thread core/src/main/java/google/registry/model/common/TimeOfYear.java Fixed
Comment thread core/src/main/java/google/registry/cache/CacheModule.java Fixed
@gbrodman
gbrodman force-pushed the jedis branch 7 times, most recently from d7b0638 to f83a27f Compare April 21, 2026 20:43
@gbrodman
gbrodman requested a review from CydeWeys April 22, 2026 17:24

@CydeWeys CydeWeys left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@CydeWeys made 6 comments.
Reviewable status: 0 of 49 files reviewed, 6 unresolved discussions (waiting on gbrodman).


core/src/main/java/google/registry/cache/CacheModule.java line 145 at r5 (raw file):

                    return;
                  } catch (Exception e) {
                    // Verification failed, try the next one

Store this to a local variable outside the for loop and return it as an inner exception when throwing CertificateException below. Otherwise, as currently written, you're swallowing all exceptions that might actually contain hints as to why things aren't working, and just throwing the string "None of the server certificates were signed by the provided CA".


core/src/main/java/google/registry/cache/MultilayerDomainCache.java line 49 at r5 (raw file):

  @Nullable
  protected Domain loadFromDatabase(String domainName) {
    Instant now = clock.now();

Shouldn't this use the transaction time?


core/src/main/java/google/registry/cache/MultilayerEppResourceCache.java line 35 at r5 (raw file):

      Caffeine.newBuilder()
          .expireAfterWrite(Duration.ofHours(1))
          .maximumSize(RegistryConfig.getEppResourceMaxCachedEntries())

Just to point out that you're doubling the max number of cached entries vs what existed previously, as we used to have a combined domain and host cache and now you're having two separate ones. So at a minimum, the documentation of this option in the config file should change. (And maybe it should be two separate ones, one for domains and one for hosts.)


core/src/main/java/google/registry/cache/MultilayerHostCache.java line 42 at r5 (raw file):

  @Override
  @Nullable
  protected Host loadFromDatabase(String repoId) {

Seems like it should should return Optional<Host>


core/src/main/java/google/registry/cache/SimplifiedJedisClient.java line 52 at r5 (raw file):

  }

  /** Gets the value from the remote cache. Returns null if it does not exist. */

Why is this returning null if it doesn't exist rather than Optional<V>?


core/src/main/java/google/registry/config/files/default-config.yaml line 643 at r5 (raw file):

valkey:
  # Optional: hosts and ports for remote Valkey caching

Add information on expected format here.

We add optional Valkey caching of hosts and domains for future use. Eventually, this will allow us to pre-warm large amounts of data in Valkey for quick retrieval during actions like RDAP.

Note: this doesn't actually use the caches yet.

We use Jedis instead of Redisson for speed purposes
(https://www.instaclustr.com/blog/redis-java-clients-and-client-side-caching/)
which means that we have to implement our own multilayer cache but
that's not the worst thing in the world.

Tested on crash with logging and RDAP code that's not included in this
PR -- it behaves as you'd expect, where the local cache works for
immediate re-lookups and the remote cache works after a restart.

@gbrodman gbrodman left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@gbrodman made 6 comments.
Reviewable status: 0 of 49 files reviewed, 6 unresolved discussions (waiting on CydeWeys).


core/src/main/java/google/registry/cache/CacheModule.java line 145 at r5 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

Store this to a local variable outside the for loop and return it as an inner exception when throwing CertificateException below. Otherwise, as currently written, you're swallowing all exceptions that might actually contain hints as to why things aren't working, and just throwing the string "None of the server certificates were signed by the provided CA".

good point, though we'll just do the last one


core/src/main/java/google/registry/cache/MultilayerDomainCache.java line 49 at r5 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

Shouldn't this use the transaction time?

We're not in a transaction here. This is a bit tricky because we'd reeeeeeeally rather not re-implement the foreign key loading logic here.

Anything using this cache should tolerate stale data anyway, but it's probably a good move to move the clock.now() to after the ForeignKeyUtils call.


core/src/main/java/google/registry/cache/MultilayerEppResourceCache.java line 35 at r5 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

Just to point out that you're doubling the max number of cached entries vs what existed previously, as we used to have a combined domain and host cache and now you're having two separate ones. So at a minimum, the documentation of this option in the config file should change. (And maybe it should be two separate ones, one for domains and one for hosts.)

depending on configuration, it may end up being less than double, actually.

Previously we have fk->resource cache and repoId->resource caches (though the latter is currently disabled at least in prod right now). This adds fk->domain and repoId->host caches, but once we're done with the code changes, the pubapi instances will only use these new caches and the frontend instances will only use the old cache(s).

But no matter what, we should absolutely CRANK this anyway. It's currently set at the default, which is 500. EppResources are not that big.


core/src/main/java/google/registry/cache/MultilayerHostCache.java line 42 at r5 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

Seems like it should should return Optional<Host>

Done.


core/src/main/java/google/registry/cache/SimplifiedJedisClient.java line 52 at r5 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

Why is this returning null if it doesn't exist rather than Optional<V>?

mostly just trying to mirror the cache / jedis API

i don't have a strong opinion on the forever-argument of when to use optional vs null, so let's use optionals


core/src/main/java/google/registry/config/files/default-config.yaml line 643 at r5 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

Add information on expected format here.

Done.

@gbrodman gbrodman left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

ptal

@gbrodman made 1 comment.
Reviewable status: 0 of 49 files reviewed, 6 unresolved discussions (waiting on CydeWeys).

@CydeWeys CydeWeys left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@CydeWeys resolved 6 discussions.
Reviewable status: 0 of 49 files reviewed, all discussions resolved.

@CydeWeys CydeWeys left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@CydeWeys reviewed 49 files and all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on gbrodman).

@gbrodman
gbrodman added this pull request to the merge queue Apr 24, 2026
Merged via the queue into google:master with commit 8cf222d Apr 24, 2026
10 checks passed
@gbrodman
gbrodman deleted the jedis branch April 24, 2026 20:44
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.

3 participants