Groupcache: Praktik terbaik untuk sering memperbarui entri cache

Dibuat pada 8 Mar 2015  ·  9Komentar  ·  Sumber: golang/groupcache

Pertanyaan saya agak mirip dengan masalah https://github.com/golang/groupcache/issues/3 .

Saya memiliki peta yang saat ini dikelola dalam RAM aplikasi go pada satu instance. Saya ingin membagikan peta ini di antara beberapa instance untuk penskalaan. Saya sudah menggunakan konsul untuk menemukan instance rekan dan saat ini saya sedang menyelesaikan ini dengan redis, namun saya tidak senang dengan kenyataan bahwa saya tidak memanfaatkan RAM setiap mesin (jadi dalam pengertian itu saya merasa redis lebih merupakan DB daripada a cache). Ini adalah salah satu alasan mengapa saya menyukai groupcache.

Saya memiliki kendala: peta saya berubah setiap saat (saya mendapatkan permintaan untuk memperbaruinya melalui http). Jadi untuk kunci K1 di peta, kemungkinan m[K1] akan diperbarui sangat sering (mungkin setiap satu detik atau kurang).

Jadi pertanyaan saya adalah:

  1. Apakah saya memilih arsitektur yang salah? Haruskah saya menggunakan sesuatu seperti Redis atau memecached?
  2. Jika groupcache adalah solusi yang baik untuk kasus penggunaan saya, apakah saya harus terus-menerus menghapus dan menambahkan (katakanlah dalam cache LRU) atau apakah ada cara yang lebih cerdas?

Terima kasih!

Komentar yang paling membantu

Hai @orcaman. Saya hanyalah pengguna Groupcache, tetapi saya harap saya dapat menjawab pertanyaan Anda.

Pertama-tama, dua hal yang paling penting untuk diingat adalah bahwa Groupcache adalah cache readthrough-only, artinya Anda tidak dapat memperbarui kunci di dalamnya. dan kedua, data tersebut dianggap tidak dapat diubah dan tidak akan kedaluwarsa. Ini pada dasarnya hanya LRU terdistribusi. Jadi jika Anda perlu sering memperbarui kunci, GC bukanlah pilihan yang baik.

Namun Anda dapat meniru kedaluwarsa atau mengubah data yang ada dengan manipulasi kunci.

Dalam kasus saya, saya membutuhkan kedaluwarsa sekitar satu jam untuk kunci. Apa yang saya lakukan adalah menambahkan stempel waktu jam putaran berikutnya ke kunci apa pun yang saya coba dapatkan. Jadi ketika satu jam berlalu, bagian kunci yang diminta aplikasi saya ini, dan dari sudut pandang Groupcache, saya meminta kunci baru. Yang lama akan diusir melalui mekanisme LRU karena tidak ada yang menyentuhnya lagi.

Tetapi jika Anda perlu terus-menerus menulis kunci, dan kedaluwarsa pada resolusi kedua, Anda mungkin lebih baik menggunakan redis atau memcache. Saya akan memilih memcache karena lebih mudah untuk menskalakan dengan lebih banyak server.

Semua 9 komentar

Hai @orcaman. Saya hanyalah pengguna Groupcache, tetapi saya harap saya dapat menjawab pertanyaan Anda.

Pertama-tama, dua hal yang paling penting untuk diingat adalah bahwa Groupcache adalah cache readthrough-only, artinya Anda tidak dapat memperbarui kunci di dalamnya. dan kedua, data tersebut dianggap tidak dapat diubah dan tidak akan kedaluwarsa. Ini pada dasarnya hanya LRU terdistribusi. Jadi jika Anda perlu sering memperbarui kunci, GC bukanlah pilihan yang baik.

Namun Anda dapat meniru kedaluwarsa atau mengubah data yang ada dengan manipulasi kunci.

Dalam kasus saya, saya membutuhkan kedaluwarsa sekitar satu jam untuk kunci. Apa yang saya lakukan adalah menambahkan stempel waktu jam putaran berikutnya ke kunci apa pun yang saya coba dapatkan. Jadi ketika satu jam berlalu, bagian kunci yang diminta aplikasi saya ini, dan dari sudut pandang Groupcache, saya meminta kunci baru. Yang lama akan diusir melalui mekanisme LRU karena tidak ada yang menyentuhnya lagi.

Tetapi jika Anda perlu terus-menerus menulis kunci, dan kedaluwarsa pada resolusi kedua, Anda mungkin lebih baik menggunakan redis atau memcache. Saya akan memilih memcache karena lebih mudah untuk menskalakan dengan lebih banyak server.

Terima kasih @dvirsky !
Saya pikir saya mendapatkan gambarnya.

Tidak masalah, meskipun saya agak berharap untuk lebih banyak adopsi Groupcache di kancah Israel. Apakah Anda tahu ada perusahaan lain yang menggunakannya? :)

Kami mungkin masih menggunakannya, hanya menunggu use case yang tepat. :-)
Saya tidak tahu banyak penjual di kancah Israel jadi saya tidak akan tahu tentang pengguna Groupcache. Menantikan untuk bertemu Anda di go meetup mendatang (jika Anda datang, itu).

Dingin. Kami menggunakannya sebagai cache HTTP keluar (yaitu permintaan cache yang kami buat ke pihak ketiga). Kami mungkin akan membuka implementasi ini kapan-kapan.
Tidak yakin tentang pertemuan Go, semoga saya berhasil.

@dvirsky dan @bradfitz - Dalam kasus penggunaan saya, saya ingin menangani TTL [Berencana untuk menambahkan stempel waktu jam saat ini ke kunci]. Saya punya pertanyaan berikut,

1.Bagaimana mekanisme LRU menghilangkan kunci. Bisakah kita mengatur durasi minimum kunci tidak digunakan [untuk menandainya sebagai kedaluwarsa]?
2.Jika tidak, apakah ini tergantung pada memori yang dialokasikan untuk cache. Ketika data melebihi alokasi yang paling terakhir digunakan akan dihapus? Dalam hal ini, bagaimana kita bisa menangani keseimbangan memori untuk tidak menghapus data jam saat ini?

Bisakah Anda memberikan beberapa saran untuk ini?

@dvirsky Terima kasih atas jawaban Anda yang luar biasa .. Namun apakah Anda melihat lonjakan kecil CPU&Memori setiap jam ketika item "diusir" pada saat yang sama?

@qbig itu tergantung pada bagaimana Anda menerapkan kedaluwarsa. Inilah yang saya lakukan:

// turn a ttl into an expiration timestamp, using discrete time windows.
// i.e. ask for an hour and get the nearest hour end as the expiration point.
//
// We pad these discrete boundaries  pseudo random margin (based on hashing the key)
// to avoid hitting the cache too hard if all requests expire at once
//
// This can be seconds from now even if you cache for days :)
func calcExpiration(ttl int64, key string, now int64) int64 {
    //we calculate the non discrete expiration, relative to current time
    expires := now

    var padding int64 = 0
    if ttl > 0 {
        // now we want to pad it so we'll no expire all reqeusts for a given time window at once
        // to be consistent, the seed of the padding is a hash on the url
        h := fnv.New32a()
        h.Write([]byte(key))
        padding = int64(h.Sum32()) % ttl

               // not sure this is correct - I wrote it long ago :)
        expires += (ttl - (expires % ttl)) - padding
        if expires < now {
            expires += ttl
        }

    }

    return expires

}

@orcaman lihat ke https://tarantool.org/

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

abennett picture abennett  ·  3Komentar

AlexanderChen1989 picture AlexanderChen1989  ·  6Komentar

yml picture yml  ·  3Komentar

cowboyrushforth picture cowboyrushforth  ·  5Komentar

amrabed picture amrabed  ·  4Komentar