Konfigurasi - Amazon ElastiCache untuk Redis

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.

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. Mengaktifkan opsi ini mengurangi kebutuhan untuk menangani koneksi gagal selama runtime perintah.

Pastikan Anda mengatur batas waktu Koneksi berdasarkan persyaratan aplikasi dan beban kerja Anda. Untuk informasi lebih lanjut, lihat bagian timeout dalam topik ini.

ClusterClientOption: Mode Cluster Diaktifkan opsi klien

Aktifkan AutoReconnectketika koneksi hilang.

Atur CommandTimeout. Untuk detail lebih lanjut, lihat bagian timeout dalam topik ini.

Atur NodeFilter untuk menyaring node yang gagal dari topologi. Selada menyimpan semua node yang ditemukan dalam output 'cluster nodes' (termasuk node dengan status PFAIL/FAIL) di 'partisi' klien (juga dikenal sebagai pecahan). Selama proses pembuatan topologi cluster, ia mencoba untuk terhubung ke semua node partisi. Perilaku selada menambahkan node gagal ini dapat menyebabkan kesalahan koneksi (atau peringatan) ketika node diganti karena alasan apa pun.

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. Hal ini memungkinkan pembaruan topologi klaster periodik sehingga klien memperbarui topologi cluster dalam interval RefreshPeriod (default: 60 detik). Ketika dinonaktifkan, klien memperbarui topologi klaster hanya ketika kesalahan terjadi ketika mencoba untuk menjalankan perintah terhadap cluster.

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. Hal ini memungkinkan penyegaran topologi adaptif yang menggunakan semua pemicu: MOVED_REDIRECT, ASK_REDIRECT, PERSISTENT_RECONNECTS, UNCOVERED_SLOT, UNKNOWN_NODE. Pemicu penyegaran adaptif memulai pembaruan tampilan topologi berdasarkan peristiwa yang terjadi selama operasi klaster Redis. Mengaktifkan opsi ini mengarah ke penyegaran topologi langsung ketika salah satu pemicu sebelumnya terjadi. Penyegaran yang dipicu adaptif dibatasi tarif menggunakan batas waktu karena peristiwa dapat terjadi dalam skala besar (batas waktu default antara pembaruan: 30).

Aktifkan closeStaleConnections. Ini memungkinkan penutupan koneksi basi saat menyegarkan topologi cluster. Ini hanya berlaku jika ClusterTopologyRefreshOptions. isPeriodicRefreshEnabled () benar. Ketika diaktifkan, klien dapat menutup koneksi basi dan membuat yang baru di latar belakang. Hal ini mengurangi kebutuhan untuk menangani koneksi gagal selama runtime perintah.

Aktifkan dynamicRefreshResources. Kami menyarankan dynamicRefreshResources untuk mengaktifkan cluster kecil, dan menonaktifkannya untuk cluster besar. dynamicRefreshResourcesmemungkinkan menemukan node cluster dari node seed yang disediakan (misalnya, endpoint konfigurasi cluster). Ia menggunakan semua node yang ditemukan sebagai sumber untuk menyegarkan topologi cluster.

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 DnsResolverdengan DirContextDnsResolver. DNS resolver didasarkan pada com.sun.jndi.dns Java. DnsContextFactory.

Konfigurasikan reconnectDelay dengan backoff eksponensial dan jitter penuh. Selada memiliki mekanisme coba ulang bawaan berdasarkan strategi backoff eksponensial.. Untuk detailnya, lihat Exponential Backoff dan Jitter di Blog Arsitektur. AWS Untuk informasi lebih lanjut tentang pentingnya memiliki strategi backoff coba lagi, lihat bagian logika backoff dari posting blog Praktik Terbaik di Blog Database. AWS

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();