Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Konfigurasi
Bagian ini menjelaskan opsi konfigurasi Java dan Lettuce yang direkomendasikan, dan bagaimana mereka berlaku untuk ElastiCache cluster.
Rekomendasi di bagian ini diuji dengan Lettuce versi 6.2.2.
Topik
Java DNS tembolok TTL
Mesin virtual JVM menyimpan cache pencarian nama DNS. Ketika JVM menyelesaikan nama host ke alamat IP untuk jangka waktu tertentu, yang disebut (TTL). time-to-live
Pilihan nilai TTL adalah trade-off antara latensi dan responsif terhadap perubahan. Dengan TTL yang lebih pendek, resolver DNS melihat pembaruan di DNS klaster lebih cepat. Hal ini dapat membuat aplikasi Anda merespons lebih cepat penggantian atau alur kerja lain yang dialami klaster Anda. Namun, jika TTL terlalu rendah, itu meningkatkan volume kueri, yang dapat meningkatkan latensi aplikasi Anda. Meskipun tidak ada nilai TTL yang benar, ada baiknya mempertimbangkan lamanya waktu yang Anda mampu menunggu perubahan berlaku saat menetapkan nilai TTL Anda.
Karena ElastiCache node menggunakan entri nama DNS yang mungkin berubah, kami sarankan untuk mengonfigurasi JVM Anda dengan TTL rendah 5 hingga 10 detik. Hal ini dapat memastikan bahwa ketika alamat IP baru sumber daya dengan meminta kembali DNS.
Pada beberapa konfigurasi JVM ditetapkan sehingga tidak pernah menyegarkan entri DNS hingga JVM dimulai ulang.
Untuk detail tentang cara mengatur JVM TTL Anda, lihat Cara mengatur JVM TTL.
Versi selada
Kami merekomendasikan untuk menggunakan Lettuce versi 6.2.2 atau versi yang lebih baru.
Endpoint
Ketika Anda menggunakan cluster mode diaktifkan cluster, atur redisUri
ke endpoint konfigurasi cluster. Pencarian DNS untuk URI ini mengembalikan daftar semua node yang tersedia di klaster, dan diselesaikan secara acak ke salah satu dari mereka selama inisialisasi klaster. Untuk detail selengkapnya tentang cara kerja penyegaran topologi, lihat dynamicRefreshResourcesnanti di topik ini.
SocketOption
Aktifkan KeepAlive
Pastikan Anda mengatur batas waktu Koneksi
ClusterClientOption: Mode Cluster Diaktifkan opsi klien
Aktifkan AutoReconnect
Atur CommandTimeout
Atur NodeFilter untuk menyaring
Misalnya, setelah failover selesai dan cluster memulai proses pemulihan, sementara ClusterTopology semakin segar, peta node bus cluster memiliki waktu singkat bahwa node bawah terdaftar sebagai node FAIL, sebelum benar-benar dihapus dari topologi. Selama periode ini, klien Lettuce Redis menganggapnya sebagai simpul yang sehat dan terus terhubung dengannya. Hal ini menyebabkan kegagalan setelah mencoba kembali habis.
Misalnya:
final ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder() ... // other options .nodeFilter(it -> ! (it.is(RedisClusterNode.NodeFlag.FAIL) || it.is(RedisClusterNode.NodeFlag.EVENTUAL_FAIL) || it.is(RedisClusterNode.NodeFlag.NOADDR))) .validateClusterNodeMembership(false) .build(); redisClusterClient.setOptions(clusterClientOptions);
catatan
Node filtering paling baik digunakan dengan DynamicRefreshSources set ke true. Jika tidak, jika tampilan topologi diambil dari node benih bermasalah tunggal, yang melihat simpul utama dari beberapa pecahan sebagai gagal, itu akan menyaring node utama ini, yang akan mengakibatkan slot tidak tercakup. Memiliki beberapa node seed (kapan DynamicRefreshSources benar) mengurangi kemungkinan masalah ini, karena setidaknya beberapa node seed harus memiliki tampilan topologi yang diperbarui setelah failover dengan primer yang baru dipromosikan.
ClusterTopologyRefreshOptions: Pilihan untuk mengontrol penyegaran topologi cluster dari klien Cluster Mode Enabled
Aktifkan enablePeriodicRefresh
Dengan opsi ini diaktifkan, Anda dapat mengurangi latensi yang terkait dengan menyegarkan topologi klaster dengan menambahkan pekerjaan ini ke tugas latar belakang. Sementara penyegaran topologi dilakukan dalam pekerjaan latar belakang, itu bisa agak lambat untuk cluster dengan banyak node. Hal ini karena semua node sedang ditanyakan untuk pandangan mereka untuk mendapatkan tampilan klaster yang paling diperbarui. Jika Anda menjalankan cluster besar, Anda mungkin ingin meningkatkan periode.
Aktifkan enableAllAdaptiveRefreshTriggers
Aktifkan closeStaleConnections
Aktifkan dynamicRefreshResources
Menggunakan query refresh dinamis semua node ditemukan untuk topologi klaster dan mencoba untuk memilih tampilan klaster yang paling akurat. Jika diatur ke false, hanya node seed awal yang digunakan sebagai sumber untuk penemuan topologi, dan jumlah klien yang diperoleh hanya untuk node seed awal. Ketika dinonaktifkan, jika endpoint konfigurasi cluster diselesaikan ke node gagal, mencoba untuk me-refresh tampilan klaster gagal dan mengarah ke pengecualian. Skenario ini dapat terjadi karena membutuhkan beberapa waktu sampai entri node gagal dihapus dari endpoint konfigurasi cluster. Oleh karena itu, endpoint konfigurasi masih dapat diselesaikan secara acak ke node yang gagal untuk waktu yang singkat.
Namun, ketika diaktifkan, kita menggunakan semua node cluster yang diterima dari tampilan klaster untuk meminta tampilan mereka saat ini. Karena kita menyaring node gagal dari tampilan itu, refresh topologi akan berhasil. Namun, ketika dynamicRefreshSources benar, Lettuce query semua node untuk mendapatkan tampilan cluster, dan kemudian membandingkan hasilnya. Jadi bisa mahal untuk cluster dengan banyak node. Kami menyarankan agar Anda mematikan fitur ini untuk cluster dengan banyak node.
final ClusterTopologyRefreshOptions topologyOptions = ClusterTopologyRefreshOptions.builder() .enableAllAdaptiveRefreshTriggers() .enablePeriodicRefresh() .dynamicRefreshSources(true) .build();
ClientResources
Konfigurasikan DnsResolver
Konfigurasikan reconnectDelay
ClientResources clientResources = DefaultClientResources.builder() .dnsResolver(new DirContextDnsResolver()) .reconnectDelay( Delay.fullJitter( Duration.ofMillis(100), // minimum 100 millisecond delay Duration.ofSeconds(10), // maximum 10 second delay 100, TimeUnit.MILLISECONDS)) // 100 millisecond base .build();
Timeout
Gunakan nilai batas waktu koneksi yang lebih rendah daripada batas waktu perintah Anda. Selada menggunakan pembentukan koneksi malas. Jadi jika batas waktu connect lebih tinggi dari batas waktu perintah, Anda dapat memiliki periode kegagalan terus-menerus setelah penyegaran topologi jika Selada mencoba terhubung ke node yang tidak sehat dan batas waktu perintah selalu terlampaui.
Gunakan batas waktu perintah dinamis untuk perintah yang berbeda. Kami merekomendasikan Anda mengatur timeout perintah berdasarkan durasi yang diharapkan. Misalnya, gunakan batas waktu yang lebih lama untuk perintah yang melakukan iterasi pada beberapa kunci, seperti skrip FLUSHDB, FLUSHALL, KEYS, SMEMBERS, atau Lua. Gunakan timeout yang lebih pendek untuk perintah kunci tunggal, seperti SET, GET, dan HSET.
catatan
Timeout yang dikonfigurasi dalam contoh berikut adalah untuk pengujian yang menjalankan perintah SET/GET dengan kunci dan nilai hingga 20 byte. Waktu pemrosesan bisa lebih lama ketika perintah kompleks atau kunci dan nilainya lebih besar. Anda harus mengatur batas waktu berdasarkan kasus penggunaan aplikasi Anda.
private static final Duration META_COMMAND_TIMEOUT = Duration.ofMillis(1000); private static final Duration DEFAULT_COMMAND_TIMEOUT = Duration.ofMillis(250); // Socket connect timeout should be lower than command timeout for Lettuce private static final Duration CONNECT_TIMEOUT = Duration.ofMillis(100); SocketOptions socketOptions = SocketOptions.builder() .connectTimeout(CONNECT_TIMEOUT) .build(); class DynamicClusterTimeout extends TimeoutSource { private static final Set<ProtocolKeyword> META_COMMAND_TYPES = ImmutableSet.<ProtocolKeyword>builder() .add(CommandType.FLUSHDB) .add(CommandType.FLUSHALL) .add(CommandType.CLUSTER) .add(CommandType.INFO) .add(CommandType.KEYS) .build(); private final Duration defaultCommandTimeout; private final Duration metaCommandTimeout; DynamicClusterTimeout(Duration defaultTimeout, Duration metaTimeout) { defaultCommandTimeout = defaultTimeout; metaCommandTimeout = metaTimeout; } @Override public long getTimeout(RedisCommand<?, ?, ?> command) { if (META_COMMAND_TYPES.contains(command.getType())) { return metaCommandTimeout.toMillis(); } return defaultCommandTimeout.toMillis(); } } // Use a dynamic timeout for commands, to avoid timeouts during // cluster management and slow operations. TimeoutOptions timeoutOptions = TimeoutOptions.builder() .timeoutSource( new DynamicClusterTimeout(DEFAULT_COMMAND_TIMEOUT, META_COMMAND_TIMEOUT)) .build();