2013-05-30 25 views
15

Bir web uygulaması çalıştırıyoruz ve önbelleğe almak için memcached redis (2.4) konumuna geçiyoruz. Şimdi biz tekrar redis performansı hakkında biraz hayal kırıklığına uğradık. Redis aynı sunucuda çalışıyor ve sadece çok basit GET ve SET işlemlerini kullanıyoruz. Önbelleğe alınan değerlerin yoğun kullanılmasını gerektiren bazı taleplerde, en fazla 300 GET isteğimiz bulunmaktadır, ancak bu talepler 150 milyona kadar çıkmaktadır. Yaklaşık 200.000 aktif tuşumuz ve saniyede yaklaşık 1.000 tekrarlama isteğimiz var. Disk io, ram veya cpu ile ilgili bir sorun yoktur. Mevcut kodumuzdan dolayı redis isteklerini birlikte gruplayamayız. Memcached yaklaşık 4 kat daha hızlı olmuştur. Redis hakkında sevdiğimiz şey, herhangi bir önbellek ısınmasına ihtiyacımız olmaması ve gelecekte daha gelişmiş veri deposu özelliklerini kullanabilmemiz. Redis'in memcached ile benzer performans göstermesini bekledik. Bu yüzden, temelde varsayılan konfigürasyon olan konfigürasyonumuzdaki bir şeyi kaçırdık.Redis Performans ayarlama

Yeniden yükleme performans ayarı için en iyi uygulamalardan biliyor musunuz?

+0

Redis aynı sunucuda ne ile çalışıyor? Müşteri veya memcached çalışan biri? Bir Redis isteği için 150ms, takas/disk, bellek değil ya da 300 istek için 150ms anlamına mı geliyor? –

+0

Saniyede yaklaşık 100 apache isteği ile bir web uygulaması. Redis, web uygulamasının kendisi ve mysql veritabanı sunucusuyla aynı ana bilgisayarda çalışıyor, ancak apache'yi yakında 3 yük dengeleyici sunucuya taşımayı planlıyoruz. Mevcut sunucu yaklaşık 64 GB RAM'e sahip, redis yaklaşık 100MB’dir. Yeterli ücretsiz ram var ve işlemci ya da io ile ilgili bir sorun yok. Sunucu diske değişmiyor. Ve evet, 300 istek için 150ms demek istedim, ama memcached aynı şartlar altında sadece 40ms aldı. – ak2

+1

Düşünebildiğim tek şey, web isteği başına bir yerine tüm istekler için Redis ile paylaşılan bir bağlantı kullanıyorsanız, Redis ile gecikme sorunları yaşayabilirsiniz, ancak saniyede 1000 istekte bu gecikme gecikmesini görmemelisiniz. Üzgünüm, bugün benim yönümden hiçbir şey gerçekten yararlı değil :) –

cevap

21

İlk olarak, the Redis benchmark page'u okumak isteyebilirsiniz. Redis ayarını kontrol etmek için ana noktaların iyi bir özetini sağlar.

Hatta pipelining kullanmadığınızı varsayalım, 300 GET'leri 150 ms içinde bu kadar verimli değil. Ortalama gecikme 500 kişi demektir. Ancak, aslında nesnelerinizin boyutuna bağlıdır. Daha büyük nesneler, daha fazla gecikme. Çok eski 2 GHz AMD kutumda, küçük nesneler (birkaç bayt) için 150 adet gecikmeyi ölçebilirim.

hızla Redis örneğinin ortalama gecikme kontrol etmek için kullanabilirsiniz:

$ redis-cli --latency 

bu seçeneği almak için son Redis sürümü (değil 2.4) kullandığınızdan emin olun. Not: 2.4 artık çok eski, Redis 2.6 kullanın - gerekirse kendi Redis sürümünüzü derleyin, gerçekten basittir.

hızla gecikmeyi incelemek için bir kriter çalıştırmak için başlatabilirsiniz:

$ redis-benchmark -q -n 10000 -c 1 -d average_size_of_your_objects_in_bytes 

Benzersiz bir bağlantı ve hiçbir boru hattı ile çalışır, bu nedenle gecikme throughput çıkarılabilir edilebilir. Bu referansların sonucunu, uygulamanızla ölçülen rakamlarla karşılaştırmaya çalışın.

  • Redis istemci kütüphanesi

    kullanıyorsunuz:

    sen kontrol etmek isteyebilir noktaları vardır? Hangi geliştirme diliyle? Bazı betik dilleri için, verimli bir istemci almak için hiredis modülünü yüklemeniz gerekir.

  • Makineniz bir VM mi? Hangi işletim sistemi?
  • Redis bağlantısı kalıcı mı? (yani, uygulama sunucunuzun her bir HTTP isteğinde bağlanmanız/kesmeniz gerekmez).

Neden memcached ile daha iyi? Eh, tek bir memcached örneği kesinlikle daha ölçeklenebilir ve tek bir Redis örneğinden daha duyarlı olabilir, çünkü birden çok iş parçacığı üzerinde çalışabilir. Redis hızlı, ancak tek iş parçacıklı - tüm komutların yürütülmesi serileştirildi. Böylece bir bağlantı için bir bağlantı devam ettiğinde, diğer tüm istemciler beklemek zorundadır - belirli bir komutta kötü bir gecikme de tüm bekleyen komutları da etkiler. Genel olarak, düşük verimde, performans olsa da karşılaştırılabilir.

1000 q/s'de (Redis veya memcached standartlar tarafından düşük bir verim), sorununun istemci tarafında daha olası olduğunu söyleyebilirim (örn.istemci kütüphanesinin seçimi, bağlantı/bağlantı kesme, vb.), Redis sunucusunun kendisinden daha. HTTP isteğine göre bir dizi Redis sorgusu oluşturursanız, Redis'e gönderdiğiniz komutları olabildiğince uzak olarak pipelining düşünün. Verimli Redis uygulamalarını geliştirmek gerçekten önemli bir noktadır.

Uygulama sunucularınız Redis ile aynı kutudaysa, Redis'e bağlanmak için TCP loopback yerine unix alan soketleri de kullanabilirsiniz. Performansı hafifçe artırır (pipelining kullanılmadığında% 50'ye varan daha fazla verim).

+0

"Tüm komutların yürütülmesi serileştirildi": Bu ifadeyle ilgili daha fazla ayrıntı verir misiniz? Bana öyle geliyor ki, bir komut başka bir komut çalıştırmıyorken, diğer bağlantılarda bile çalışabilir. Redis komuta atomisitesini nasıl kazanır? – akonsu

+0

Evet, tam olarak. Ayrıca bkz. Http://stackoverflow.com/questions/10489298/redis-is-single-threaded-then-how-does-it-do-concurrent-io/10495458#10495458 –

+0

Ayrıca bkz. Http://redis.io/topics/gecikme –

0

Redis'in OS takas belleği kullanıp kullanmadığını kontrol edin. Öyleyse bu gecikme katacak. Bulmak için, "Takas yoluyla başlatılan gecikme süresi" için arama yap: http://redis.io/topics/latency

Sunucu donanımınız NUMA uyumluysa, numisl ile redis sunucusunu daha iyi başlatın. NUMA ile redis sunucusundan başlıyorsanız, sysctl'de bölge geri alma modunu (vm.zone_reclaim_mode = 0) kapatmayı unutmayın.

0

Bir Lua komut dosyasında 300 GET isteğini kodlamayı deneyin. Daha hızlı çalışmalı çünkü istemci kodunuz Redis'e yerel olarak çalışıyor olsa da TCP/IP yığınına dokunarak zamandan tasarruf edin.