Yukarı tıklayın " CSDN "Dikkat,
Kritik anda teslim edin!
Hayat sürprizlerle dolu. Milli bayram tatilinin son gününde, popüler trafik çocuğu Lu Han, aşk ilişkisini öğlen 12'de Weibo'da duyurdu.
Weibo piyasaya sürüldüğünde, Moments of Friends ve büyük web sitelerinin manşetlerini anında patlattı ve bu da Weibo'nun bir süre felç olmasına neden oldu. Mikroblog servisi de çaresizce ifade etti: Herkes tam olarak nasıl olduğunu biliyor.
Bununla birlikte, tüm olayda, sayısız ezilmiş kızın kalbinin yanı sıra, hala kendini adamış en masum küçük kardeş Weibo arama mühendisi Ding Zhenkai'dir.Düğün günü Luhan aşk ilişkisini açıkladı ve ziyafeti bırakmak zorunda kaldı. Weibo istisnasıyla uğraştıktan sonra düğün devam etti ve küçük kardeşim üç saniye üzüldü ...
Geriye dönüp baktığımızda, ne kadar trafik Zeng Haoyan'ı "Weibo sunucusu kararlıdır ve aynı anda üç çift hile yapabilir". Spesifik veriler aşağıdaki şekilde gösterilmiştir:
Weibo yıldız gücü listesindeki her listenin puanlama yöntemine göre: dört maddeden oluşan 100 puanlık tam puan: sırasıyla% 30,% 30,% 20 ve% 20'yi oluşturan okuma sayısı, etkileşim sayısı, sosyal etki ve hayranlık değeri .
Lu Han tarafından yayınlanan Weibo'nun her öğesinin en yüksek değerine ulaştığı yukarıdan görülebilir.Böyle yüksek trafik durumunda, bir geliştirici olarak sistem performansını hızlı bir şekilde iyileştirmenin iyi bir yolu var mı?
Daha sonra, CSDN blog uzmanından "üçüncül endüstriyi çıkarın", konuk web yöneticisini alın ve yaygın olarak önbellek, Oturum paylaşımı ara yazılımı, dağıtılmış kilit vb. Olarak kullanılan en popüler Anahtar-Değer veritabanını bizimle paylaşın. - Redis teknolojisi .
Açıklama: Bu makaleyi okumak belirli bir miktarda Web geliştirme deneyimi gerektirir.En iyisi, Redis hakkında temel bir anlayışa sahip olmaktır.Makalenin sonundaki ek, size bazı ilgili makaleler de sağlayacaktır.Bu makale, Redis uygulamasını önbellek geliştirmeye sınırlamak içindir. Personel, Redis'in daha olası uygulama senaryolarını anlıyor. Alan sınırlamaları nedeniyle, makaledeki birçok senaryo yalnızca gerçekleştirme fikirlerini ve bazı ilkeleri gösterir ve yalnızca bazı işlevlerin belirli bir şekilde gerçekleştirilmesini sağlar.
Modern Yüksek Eş Zamanlı Karmaşık Sistemlerin Karşılaştığı Zorluklar
Modern sistemlerin işlevlerinin karmaşıklığıyla birlikte, sonsuz bir akışta çeşitli ihtiyaçlar ortaya çıkar.Artan karmaşık iş sistemleri, daha büyük ve daha büyük kullanıcı grupları ve kullanıcıların giderek artan deneyim gereksinimleri karşısında performans daha önemli hale gelir. .
Kod mantığı ve sunucu performansıyla ilgili sorunların yanı sıra, performansı artırmanın birkaç yolu vardır:
Dinamik ve statik ayırma
Yük dengeleme
dağıtılmış
Kümeleme
Önbellek
Mevcut limit işleme
Veri sıkıştırma
diğer
Yük dengeleme, dağıtım ve kümeleme ile ilgili sorunları inceleyelim:
Konfigürasyon yönetimi karmaşık hale geldiğinden, bu sorunu çözmek için bir konfigürasyon merkezinin kurulması gerekir.
Aynı kullanıcının isteği farklı Web sunucularına iletilecek ve bu da oturum kaybı gibi sorunlara yol açacaktır.
Aynı talep, veri tutarlılığını sağlamak için dağıtılmış işlemler gerektiren dağıtılmış bir ortamda farklı işlemler sağlamak için farklı hizmetler gerektirir.
Dağıtılmış benzersiz kimlik sorunu.
Ek olarak, sistemin farklı bölümlerindeki bazı belirli sorunlar için başka özel iş gereksinimleri vardır:
IP istatistikleri
Kullanıcı giriş kaydı istatistikleri
Gerçek zamanlı liderlik tablosu
Atom sayısı
son yorum
Yukarıdaki sorunlara çeşitli çözümlerin olduğu doğrudur, örneğin:
Yapılandırma merkezi Zookpeer, Redis, vb. Kullanılarak uygulanabilir.
Oturum kaybı, aralarında Oturum paylaşımının farklı uygulamalara bölünebildiği Oturum senkronizasyonu, istemci belirteci, Oturum paylaşımı vb. Kullanılarak çözülebilir.
Sonsuz kavramlar ve çeşitli gelişen teknolojiler karşısında, genellikle güçsüz görünüyoruz, bu yüzden bu sorunları çözebilecek sihirli bir değnek var mı?
Redis sihirli bir değnek değil ama çok yakın
Burada önerdiğim Redis. Gerçek gümüş mermiden hala biraz uzakta olmasına rağmen, gümüş kurşuna yakın birkaç çözümden biri:
Redis, C'de geliştirilmiştir. Minimal mimari tasarıma ve üstün performansa sahip bir bellek K / V veritabanıdır.
Redis, eşzamanlılığın neden olduğu kilit performans kaybı gibi sorunları önlemek için tek iş parçacıklı bir çoklama tasarımı kullanır.
Redis'in kurulumu, test edilmesi, yapılandırılması ve çalıştırılması diğer ürünlere göre daha kolaydır.
Redis, açık ara en popüler K / V veritabanıdır, kalıcılığı destekler ve değer, birden çok veri yapısını destekler.
Redis komut söz dizimi basit ve ustalaşması kolaydır.
Redis, çeşitli programlama dillerinin kendisiyle etkileşim kuran istemciler geliştirmesini kolaylaştıran ortak bir protokol sağlar.
Redis açık kaynaktır, ikincil geliştirme yoluyla özelleştirebilir ve optimize edebiliriz.
Redis şu anda iyi bir topluluk bakımına sahiptir, sürüm yinelemeleri garanti edilmektedir ve yeni işlevler düzenli bir şekilde ekleniyor ve geliştiriliyor.
Redis, iyi bir ana-bağımlı çoğaltma ve küme ile ilgili desteğe sahiptir.
En son sürüm, kolayca genişletilebilen modüler işlevler sağlar.
Ardından, yukarıda belirtilen sorunları çözmek için Redis'in nasıl kullanılacağından bahsedelim:
1. Yapılandırma Merkezi
Redis'in kendisi, hash, set ve list gibi beş veri yapısını destekleyen bir bellek K / V veritabanıdır, böylece konfigürasyon bilgilerinin saklama ve okuma hızı karşılanabilir.Redis ayrıca, konfigürasyon değiştiğinde abonelik / yayınlama işlevleri de sağlar. İlgili yapılandırmaları güncellemeleri için farklı sunuculara bildirimde bulunun.
2. Dağıtılmış kilit
Redis'in SETNX komutunu veya SET komutunu NX seçenekleri ve sona erme süresi ve diğer işlevlerle kullanmak, üstün performansla dağıtılmış bir kilidi kolayca gerçekleştirebilir.
3. Önbellek
Redis, birden çok süre sonu ve eleme mekanizmasını destekler ve kendi performans avantajları da Redis'in önbelleğe alma işleminde yaygın olarak kullanılmasını sağlar.
4. Lua betiği
Lua, standart C dili ve açık kaynak ile yazılmış, hafif ve kompakt bir betik dilidir. Redis, birçok karmaşık işlevi gerçekleştirmek için Redis'teki komutları genişletebilen Lua komut dosyalarının çalışmasını destekler.
Redis, bazı kombinasyonel komut mantığı işlemeyi uygulamak için Lua komut dosyalarının kullanılmasını destekler, böylece Redis, mevcut sınırlama ve dağıtılmış benzersiz kimlik ile ilgili teknolojilerin uygulanması olarak kullanılabilir.
5. Redis, BitMap'leri destekler
Bitmap (bitmap), indekslemede, veri sıkıştırmada vb. Yaygın olarak kullanılan ve aynı zamanda depolama alanı ve hızının optimizasyonunu sağlayabilen (zaman için yer değiştirmeye gerek kalmadan) çok yaygın olarak kullanılan bir yapıdır.
Redis'in BitMap'lerini kullanıcı oturum açma kaydı istatistikleri olarak kullanmak, sadece istatistik hızı son derece hızlı değil, aynı zamanda bellek kullanımı da son derece düşük.
6. Redis, HyperLogLog algoritmasını destekler
Redis HyperLogLog, az miktarda bellekle kümedeki benzersiz öğelerin sayısının yaklaşık bir değerini sağlamak için rasgeleleştirmeyi kullanan bir algoritmadır.
HyperLogLog, birden çok öğeyi girdi olarak kabul edebilir ve girdi öğelerinin önemine ilişkin bir tahmin verebilir:
HyperLogLog'un avantajı, giriş öğelerinin sayısı veya hacmi çok büyük olsa bile, tabanı hesaplamak için gereken alanın her zaman sabit ve küçük olmasıdır.
Redis'te, her HyperLogLog anahtarı 2 ^ 64'e yakın farklı öğenin tabanını hesaplamak için yalnızca 12 KB belleğe ihtiyaç duyar. Bu, kardinalite hesaplanırken daha fazla öğenin daha fazla bellek tükettiği bir koleksiyonun tam tersidir. HyperLogLog algoritmasını kullanarak, verilerde küçük hatalara izin veren IP istatistikleri gibi istatistiksel işlevleri kolayca uygulayabiliriz.
Baz: Koleksiyondaki farklı öğelerin sayısı. Örneğin, {"elma", "muz", "kiraz", "muz", "elma"} 'nın tabanı 3'tür.
tahmini değer: Algoritma tarafından verilen temel sayı doğru değildir ve gerçek sayıdan biraz daha fazla veya daha az olabilir, ancak makul bir aralıkta kontrol edilecektir.
7. Redis, Geo işlevini destekler
Coğrafi konumla ilgili yönetimi sağlamak için Redis tabanlı kullanabiliriz ve yakındaki insanlar ve iki coğrafi konum arasındaki mesafe hesaplaması gibi işlevlerin uygulanması son derece kolay hale geldi.
8. Basit mesaj kuyruğu
Redis listesi + yayınlama / abone olma işlevi, basit bir mesaj kuyruğu oluşturabilir, mesajı Redis listesinde saklayabilir ve belirtilen üyeyi yayınlama / abone olma işlevi ile bilgilendirebilir.Üye bildirimi aldıktan sonra, bildirim içeriğine göre ilgili işlemleri gerçekleştirebilir.
9. Tam metin araması
Resmi Redis ekibi, tam metin araması için Redis'i kullanma işlevini gerçekleştirebilen RediSearch modülünü geliştirdi.
10. Dağıtılmış benzersiz kimlik
Redis'in tasarımı, birden fazla eşzamanlılık sorununu önlemeyi ve komutlarını atomik olarak çalıştırmayı mümkün kılar.Bu özellikler, dağıtılmış benzersiz bir kimlik oluşturucunun gereksinimlerini doğal olarak karşılar.
Dahası, Lua betikleri ile birleştirerek belirli kurallara sahip karmaşık benzersiz kimlikler üretebilir.
Kod uygulamasının bir parçası
Aşağıda, birkaç işlevin gerçekleştirilmesini açıklamak için Java kodunu bir gösteri olarak kullanıyoruz (programlama dili uygulaması prensipte benzerdir, ancak özel uygulama biraz farklıdır):
Oturum paylaşımı
İlke: Farklı web sunucularının oturum bilgileri tek tip olarak Redis'te saklanır ve oturum ayrıca Redis'ten alınır.
Uygulama:
Yöntem 1: Tomcat'e dayalı olarak Sessioin paylaşımını gerçekleştirin:
Tomcat yapılandırma adımları (ilgili kod kaynakları https://gitee.com/coderknock/Tomcat-Redis-Session-Manager-Demo adresinden edinilebilir):
Commons-pool2-2.4.2.jar, jedis-2.9.0.jar ve commons-pool2-2.4.2.jar'ın üç jar paketini Tomcat altındaki lib dizinine koyun (not: projenin lib dizini değil).
Tomcat conf altında context.xml'yi değiştirin:
XML
< Bağlam >
......
< Valve className = "com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" / >
< Yönetici className = "com.orangefunction.tomcat.redissessions.RedisSessionManager"
ana bilgisayar = "127.0.0.1"
bağlantı noktası = "6379"
veritabanı = "0"
maxInactiveInterval = "60"
password = "admin123" / >
......
< / Bağlam >
Yöntem 2: Fileter'a dayalı olarak, HttpServletRequestWrapper ve HttpSession'ı kendiniz uygulayın:
Anahtar kod:
HttpSessionWrapper.java
java
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.coderknock.jedis.executor.JedisExecutor;
com.coderknock.pojo.User'ı içe aktar;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
javax.servlet.ServletContext'i içe aktar;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
javax.servlet.http.HttpSession'ı içe aktarın;
javax.servlet.http.HttpSessionContext'i içe aktarın;
import java.util.Enumeration;
/ **
* < p > < / p >
*
* @author Üçüncül
* @ sürüm 1.0
* @date 2017-08-26
* @QQGroup 213732117
* @website
* @copyright Telif hakkı 2017 Nake coderknock.com Tüm hakları saklıdır.
* @ JDK 1.8'den beri
* /
public class HttpSessionWrapper, HttpSession {
korumalı son Günlük Kaydedici = LogManager.getLogger (HttpSessionWrapper.class);
private String sid = "";
özel HttpServletRequest isteği;
özel HttpServletResponse yanıtı;
özel son uzun oluşturmaTime = System.currentTimeMillis ();
özel son uzun lastAccessedTime = System.currentTimeMillis ();
// Saniye cinsinden sona erme süresi
özel int expire_time = 60;
public HttpSessionWrapper () {
}
public HttpSessionWrapper (String sid, HttpServletRequest isteği,
HttpServletResponse yanıtı) {
this.sid = sid;
this.request = istek;
this.response = yanıt;
}
public Object getAttribute (Dize adı) {
logger.info (getClass () + "getAttribute (), ad:" + ad);
Deneyin {
Nesne obj = JedisExecutor.execute (jedis- > {
Dize jsonStr = jedis.get (sid + ":" + ad);
if (jsonStr! = null || StringUtils.isNotEmpty (jsonStr)) {
jedis.expire (sid + ":" + name, expire_time); // sona erme süresini sıfırla
}
jsonStr döndür;
});
obj iad;
} catch (JSONException je) {
logger.error (je);
} catch (İstisna e) {
logger.error (e.getMessage ());
}
boş döndür;
}
public void setAttribute (Dize adı, Nesne değeri) {
logger.info (getClass () + "setAttribute (), ad:" + ad);
Deneyin {
JedisExecutor.executeNR (jedis- > {
if (value instanceof String) {
Dize değeri_ = (Dize) değeri;
jedis.set (sid + ":" + ad, değer _); // Sıradan dize nesnesi
} Başka {
jedis.set (sid + ":" + name, JSON.toJSONString (value)); // Serileştirilmiş nesne
}
jedis.expire (sid + ":" + name, expire_time); // sona erme süresini sıfırla
});
} catch (İstisna e) {
logger.error (e);
}
}
public void removeAttribute (Dize adı) {
logger.info (getClass () + "removeAttribute (), ad:" + ad);
if (StringUtils.isNotEmpty (ad)) {
Deneyin {
JedisExecutor.executeNR (jedis- > {
jedis.del (sid + ":" + ad);
});
} catch (İstisna e) {
logger.error (e);
}
}
}
// ... Kodun bir kısmını atlayın
}
SessionFilter.java
java
import com.coderknock.wrapper.DefinedHttpServletRequestWrapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
içe aktar javax.servlet. *;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
java.io.IOException ithalatı;
java.util.UUID'yi içe aktarın;
/ **
* < p > < / p >
*
* @author Üçüncül
* @ sürüm 1.0
* @date 2017-08-26
* @QQGroup 213732117
* @website
* @copyright Telif hakkı 2017 Nake coderknock.com Tüm hakları saklıdır.
* @ JDK 1.8'den beri
* /
public class SessionFilter, Filter {
korumalı son Günlük Kaydedici = LogManager.getLogger (getClass ());
private static final String host = "host";
private static final String bağlantı noktası = "bağlantı noktası";
private static final String saniye = "saniye";
public void init (FilterConfig filterConfig) ServletException {
logger.debug ("init filterConfig bilgisi");
}
public void doFilter (ServletRequest isteği, ServletResponse yanıtı,
FilterChain zinciri) IOException, ServletException {
// Çerezden sessionId al, eğer bu istek için sessionId yoksa, bu istek için bir sessionId ayarlamak için yeniden yaz
HttpServletRequest httpRequest = (HttpServletRequest) isteği;
HttpServletResponse httpResponse = (HttpServletResponse) yanıtı;
String sid = boş;
eğer (httpRequest.getCookies ()! = null) {
for (Cookie cookie: httpRequest.getCookies ()) {
eğer (cookie.getName (). equals ("JSESSIONID")) {
sid = cookie.getValue ();
kırmak;
}
}
}
if (StringUtils.isEmpty (sid)) {
Deneyin {
Çerez çerezi = yeni Çerez ("JSESSIONID", httpRequest.getLocalAddr () + ":" + request.getLocalPort () + ":" + UUID.randomUUID (). ToString (). ReplaceAll ("-", "")) ;
httpResponse.addCookie (çerez);
} catch (İstisna e) {
e.printStackTrace ();
}
}
logger.info ("JSESSIONID:" + sid);
chain.doFilter (yeni DefinedHttpServletRequestWrapper (sid, httpRequest, httpResponse), yanıt);
}
public void destroy () {
}
}
Liderler Sıralaması
İlke: Bu işlev, Redis tarafından sipariş edilen koleksiyonla kolayca gerçekleştirilebilir
Anahtar komutlar:
ZADD anahtar puanı üyesi: Liderlik tablosunda üyeleri ve puanlarını başlatın.
ZINCRBY anahtar artırma üyesi: Bir üyeye puan ekleyin, üye yoksa üye ekleyin ve puanı artırmaya ayarlayın.
ZUNIONSTORE hedef sayısal tuşlar anahtarı: Birden çok lider tablosu birleştirilebilir. Bu işlem, hedefteki birkaç kümenin birleşimini depolar, burada her kümenin aynı üyelerinin puanları üst üste getirilir veya maksimum, minimum, ortalama değer vb. (Parametrelerle belirlenir, varsayılan Birden fazla alt sıralama kuruluna göre toplam sıralamayı hesaplama işlevini gerçekleştirebilen üst üste binme).
ZREVRANGE key start stop: Bu komut, üyeleri yüksekten düşüğe doğru alabilen sıralama bilgisini elde etmek için en kritik komuttur.
Redis komut gösterimi ("#" sonrasındaki açıklama):
# 1. Birkaç lider panosu üye verilerini depolayın (burada, kendi sisteminizin mevcut verilerini Redis'e yüklemek olarak anlaşılabilir)
ZADD testi En iyi 23 üye125 üye2
# 2. Bir kişinin puanını artırın (buradaki puan kayan nokta türüne dayanmaktadır)
ZINCRBY test Top 20 üye1 # Şimdi testTop'taki üye1'in puanı programlandı 43
ZINCRBY testTop -10 üye2 # Şu anda testTop'ta üye2'nin puanı programlanmıştır 15
ZINCRBY testTop 20 üye3 # Şu anda testTop'a 20 puanla bir üye3 üye eklenmiştir
# 3. Sıralamada ilk ikisini sorgulayın ve puanlarını öğrenin [WITHSCORES seçeneği puanları görüntülemek için kullanılır, bu parametre olmadan yalnızca üye adları bulunur]
ZREVRANGE testi En iyi 01 WITHSCORES
#sonuç:
# 1) "üye1"
# 2) "43"
# 3) "üye3"
# 4) "20"
# Şu anda hala bir lider panosu olduğunu varsayarsak
ZADD testi Üst2100 üye2200 üye3123 üye4
# TestTop testTop2'yi genel bir liste başına birleştirin
ZUNIONSTORE en iyi 2 testi Top test Top2
# Genel listenin tüm üyelerinin sıralamasını sorgulayın
ZREVRANGE üst 0-1 WITHSCORES
1) "üye3"
2) "220"
3) "üye4"
4) "123"
5) "üye2"
6) "115"
7) "üye1"
8) "43"
Java ile ilgili uygulama kodu (sf.gg'nin itibar listesini simüle eden) görüntülenebilir.
https://gitee.com/coderknock/Redis-Top-And-Around
/src/test/java/TopDemo.java'nın belirli test durumları vardır
Coğrafya ile ilgili işlevler
Redis'in Geo işlevi, yakınlardaki basit bir kişiyi gerçekleştirmek için kullanılabilen, iki üye arasındaki mesafeyi, bir üyenin yakınındaki üyeleri sorgulama gibi işlevleri sağlar.
Java ile ilgili uygulama kodu şu adresten görüntülenebilir: https://gitee.com/coderknock/Redis-Top-And-Around/src/test/java/GeoDemo.java Belirli test durumları vardır.
Önbellek
İlke: Belirli kurallara göre sık erişilen veriler için bir Anahtar belirleyin ve bunu Redis'te saklayın.Her sorguda, önce Redis'in eşleşen verileri içerip içermediğini ve ardından önbellek yoksa veritabanını sorgulayın.
Not: Var olmayan veriler için, önbellek bozulmasını önlemek için kendiliğinden ayarlanmış boş bir değer depolamalı ve sona erme süresini ayarlamalısınız (çünkü veriler mevcut olmadığından, Anahtar'a karşılık gelen değeri null olarak ayarlayın (Java'da temsil) Çünkü Redis, değeri null olan anahtarı kaldıracak ve bu da her sorguda veritabanına erişilmesine neden olacaktır).
Java ile ilgili uygulama kodu görüntülenebilir: https://gitee.com/coderknock/Redis-Cache
son sözler
Bu makale sadece, belirli işlevlerin gerçekleştirilmesi gibi herkesin düşüncesini farklılaştırmayı istemektedir, sonraki alışverişlerde birlikte tartışılabilir.
Kişisel kısıtlamalar nedeniyle yazıda yanlış beyanlar olabilir, bunları yorum bölümünde birlikte tartışabilirsiniz.
ek
Redis çevre inşaatı
Çevrimiçi deneyim:
Windows sürümü: https://github.com/MSOpenTech/redis
Linux kurulumu: https://www.coderknock.com/blog/2016/05/28/LinuxRedis.html
Redis yapılandırması
https://www.coderknock.com/blog/2017/06/14/Redis%20%E9%85%8D%E7%BD%AE.html
Redis tarafından desteklenen beş veri yapısı
Redis temel bilgi genişletilmiş okuma
Redis temel bilgi genişletilmiş okuma: https://segmentfault.com/bookmark/1230000010694933
Redis yayın abonelik diyagramı