Redis
 sql >> Teknologi Basis Data >  >> NoSQL >> Redis

Eksekusi paralel dengan StackExchange.Redis?

Saat ini, kode Anda menggunakan API sinkron (StringSet ), dan sedang dimuat oleh 10 utas secara bersamaan. Ini tidak akan memberikan tantangan yang berarti bagi SE.Redis - ini berfungsi dengan baik di sini. Saya mencurigai bahwa itu benar-benar batas waktu di mana server telah memakan waktu lebih lama dari yang Anda inginkan untuk memproses beberapa data, kemungkinan besar juga terkait dengan pengalokasi server. Maka, salah satu opsinya adalah meningkatkan batas waktu sedikit . Tidak banyak... coba 5 detik, bukan default 1 detik. Kemungkinan besar, sebagian besar operasi bekerja sangat cepat.

Berkenaan dengan mempercepatnya:satu opsi di sini adalah tidak menunggu - yaitu menyimpan data perpipaan. Jika Anda puas untuk tidak memeriksa setiap pesan untuk status kesalahan, maka satu cara sederhana untuk melakukannya adalah dengan menambahkan , flags: CommandFlags.FireAndForget ke akhir StringSet . Anda panggilan. Dalam pengujian lokal saya, ini mempercepat 1 juta contoh sebesar 25% (dan saya menduga banyak waktu yang tersisa sebenarnya dihabiskan untuk serialisasi string).

Masalah terbesar yang saya miliki dengan contoh 10 juta hanyalah overhead bekerja dengan contoh 10 juta - terutama karena ini membutuhkan banyak memori untuk redis-server dan aplikasi, yang (untuk meniru pengaturan Anda) berada di mesin yang sama. Ini menciptakan tekanan memori yang bersaing, dengan jeda GC dll dalam kode yang dikelola. Tapi mungkin yang lebih penting:hanya butuh waktu lama untuk mulai melakukan sesuatu . Akibatnya, saya memfaktorkan ulang kode untuk menggunakan yield return parallel paralel generator daripada satu daftar. Misalnya:

    static IEnumerable<Person> InventPeople(int seed, int count)
    {
        for(int i = 0; i < count; i++)
        {
            int f = 1 + seed + i;
            var item = new Person
            {
                Id = f,
                Name = Path.GetRandomFileName().Replace(".", "").Substring(0, appRandom.Value.Next(3, 6)) + " " + Path.GetRandomFileName().Replace(".", "").Substring(0, new Random(Guid.NewGuid().GetHashCode()).Next(3, 6)),
                Age = f % 90,
                Friends = ParallelEnumerable.Range(0, 100).Select(n => appRandom.Value.Next(1, f)).ToArray()
            };
            yield return item;
        }
    }

    static IEnumerable<T> Batchify<T>(this IEnumerable<T> source, int count)
    {
        var list = new List<T>(count);
        foreach(var item in source)
        {
            list.Add(item);
            if(list.Count == count)
            {
                foreach (var x in list) yield return x;
                list.Clear();
            }
        }
        foreach (var item in list) yield return item;
    }

dengan:

foreach (var element in InventPeople(PER_THREAD * counter1, PER_THREAD).Batchify(1000))

Di sini, tujuan dari Batchify adalah untuk memastikan bahwa kami tidak membantu server terlalu banyak dengan meluangkan waktu yang cukup lama di antara setiap operasi - data ditemukan dalam kumpulan 1000 dan setiap kumpulan tersedia dengan sangat cepat.

Saya juga khawatir dengan kinerja JSON, jadi saya beralih ke JIL:

    public static string ToJSON<T>(this T obj)
    {
        return Jil.JSON.Serialize<T>(obj);
    }

dan kemudian hanya untuk bersenang-senang, saya memindahkan pekerjaan JSON ke dalam batching (sehingga pemrosesan yang sebenarnya berulang:

 foreach (var element in InventPeople(PER_THREAD * counter1, PER_THREAD)
     .Select(x => new { x.Id, Json = x.ToJSON() }).Batchify(1000))

Ini mengurangi waktu sedikit lebih lama, jadi saya dapat memuat 10M dalam 3 menit 57 detik, dengan kecepatan 42.194 rop. Sebagian besar waktu ini sebenarnya adalah pemrosesan lokal di dalam aplikasi. Jika saya mengubahnya sehingga setiap utas memuat sama item ITEMS / THREADS kali, maka ini berubah menjadi 1 menit 48 detik - tingkat 92.592 rop.

Saya tidak yakin apakah saya telah menjawab sesuatu dengan benar, tetapi versi singkatnya mungkin hanya "coba batas waktu yang lebih lama; pertimbangkan untuk menggunakan fire-and-forget).




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Hiredis menunggu pesan

  2. Spring Boot redisTemplate autowiring gagal

  3. Konversi DataFrame ke RDD[(String, String)]

  4. Java mengonversi byte ke string aman biner

  5. Berikan file ke Pekerjaan Aktif / pekerjaan latar belakang