Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Penguncian terdistribusi dengan DynamoDB Lock Client
Untuk aplikasi yang memerlukan semantik rilis penguncian penguncian tradisional, DynamoDB Lock Client adalah pustaka sumber terbuka yang mengimplementasikan penguncian terdistribusi menggunakan tabel DynamoDB sebagai penyimpanan kunci. Pendekatan ini berguna ketika Anda perlu mengoordinasikan akses ke sumber daya eksternal (seperti objek S3 atau konfigurasi bersama) di beberapa instans aplikasi.
Klien kunci tersedia sebagai pustaka https://github.com/awslabs/amazon-dynamodb-lock-client
Cara kerjanya
Klien kunci menggunakan tabel DynamoDB khusus untuk melacak kunci. Setiap kunci direpresentasikan sebagai item dengan atribut kunci berikut:
Kunci partisi yang mengidentifikasi sumber daya yang dikunci.
Durasi sewa yang menentukan berapa lama kunci valid. Jika pemegang kunci mogok atau menjadi tidak responsif, kunci secara otomatis kedaluwarsa setelah durasi sewa.
Detak jantung yang dikirim oleh pemegang kunci secara berkala untuk memperpanjang sewa. Ini mencegah kunci kedaluwarsa saat dudukan masih aktif diproses.
Klien kunci menggunakan penulisan kondisional untuk memastikan bahwa hanya satu proses yang dapat memperoleh kunci pada satu waktu. Jika kunci sudah ditahan, penelepon dapat memilih untuk menunggu dan mencoba lagi atau gagal segera.
Kapan menggunakan klien kunci
Klien kunci cocok ketika:
Anda perlu mengoordinasikan akses ke sumber daya bersama di beberapa instans aplikasi atau layanan mikro.
Bagian kritis berjalan lama (detik hingga menit) dan mencoba kembali seluruh operasi pada konflik akan mahal.
Anda memerlukan kedaluwarsa kunci otomatis untuk menangani kegagalan proses dengan anggun.
Contoh umum termasuk mengatur alur kerja terdistribusi, mengoordinasikan pekerjaan cron di beberapa instance, dan mengelola akses ke sumber daya eksternal bersama.
Pengorbanan
- Infrastruktur tambahan
Memerlukan tabel DynamoDB khusus untuk manajemen kunci, dengan kapasitas baca dan tulis tambahan untuk operasi kunci dan detak jantung.
- Ketergantungan jam
Kedaluwarsa kunci bergantung pada stempel waktu. Kemiringan jam yang signifikan antara klien dapat menyebabkan perilaku yang tidak terduga, terutama untuk jangka waktu sewa yang pendek.
- Risiko kebuntuan
Jika aplikasi Anda memperoleh kunci pada beberapa sumber daya, Anda harus mendapatkannya dalam urutan yang konsisten untuk menghindari kebuntuan. Durasi sewa menyediakan jaring pengaman dengan secara otomatis melepaskan kunci dari pemegang yang tidak responsif.
Implementasi
Contoh berikut menunjukkan cara menggunakan DynamoDB Lock Client untuk memperoleh dan melepaskan kunci:
import java.io.IOException; import java.util.Optional; import java.util.concurrent.TimeUnit; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; final DynamoDbClient dynamoDB = DynamoDbClient.builder() .region(Region.US_WEST_2) .build(); final AmazonDynamoDBLockClient lockClient = new AmazonDynamoDBLockClient( AmazonDynamoDBLockClientOptions.builder(dynamoDB, "Locks") .withTimeUnit(TimeUnit.SECONDS) .withLeaseDuration(10L) .withHeartbeatPeriod(3L) .withCreateHeartbeatBackgroundThread(true) .build()); // Try to acquire a lock on a resource final Optional<LockItem> lock = lockClient.tryAcquireLock(AcquireLockOptions.builder("my-shared-resource").build()); if (lock.isPresent()) { try { // Perform operations that require exclusive access processSharedResource(); } finally { // Always release the lock when done lockClient.releaseLock(lock.get()); } } else { System.out.println("Failed to acquire lock."); } lockClient.close();
penting
Selalu lepaskan kunci di finally blok untuk memastikan kunci dilepaskan bahkan jika logika pemrosesan Anda menimbulkan pengecualian. Kunci yang belum dirilis memblokir proses lain sampai sewa berakhir.
Anda juga dapat menerapkan mekanisme penguncian sederhana tanpa perpustakaan klien kunci dengan menggunakan penulisan bersyarat secara langsung. Contoh berikut menggunakan UpdateItem ekspresi kondisi untuk memperoleh kunci, dan melepas DeleteItem kannya:
from datetime import datetime, timedelta from boto3.dynamodb.conditions import Attr def acquire_lock(table, resource_name, owner_id, ttl_seconds): """Attempt to acquire a lock. Returns True if successful.""" expiry = (datetime.now() + timedelta(seconds=ttl_seconds)).isoformat() now = datetime.now().isoformat() try: table.update_item( Key={'LockID': resource_name}, UpdateExpression='SET #owner = :owner, #expiry = :expiry', ConditionExpression=Attr('LockID').not_exists() | Attr('ExpiresAt').lt(now), ExpressionAttributeNames={'#owner': 'OwnerID', '#expiry': 'ExpiresAt'}, ExpressionAttributeValues={':owner': owner_id, ':expiry': expiry} ) return True except table.meta.client.exceptions.ConditionalCheckFailedException: return False def release_lock(table, resource_name, owner_id): """Release a lock. Only succeeds if the caller is the lock owner.""" try: table.delete_item( Key={'LockID': resource_name}, ConditionExpression=Attr('OwnerID').eq(owner_id) ) return True except table.meta.client.exceptions.ConditionalCheckFailedException: return False
Pendekatan ini menggunakan ekspresi kondisi untuk memastikan bahwa kunci hanya dapat diperoleh jika tidak ada atau telah kedaluwarsa, dan hanya dapat dilepaskan oleh proses yang memperolehnya. Pertimbangkan untuk mengaktifkan Time to Live (TTL) pada tabel kunci untuk membersihkan item kunci yang kedaluwarsa secara otomatis.