1. 程式人生 > >如何用Redis實現分散式快取

如何用Redis實現分散式快取

第一:Redis 是什麼?

Redis是基於記憶體、可持久化的日誌型、Key-Value資料庫 高效能儲存系統,並提供多種語言的API.

第二:出現背景

資料結構(Data Structure)需求越來越多, 但memcache中沒有, 影響開發效率

效能需求, 隨著讀操作的量的上升需要解決,經歷的過程有:

資料庫讀寫分離(M/S)–>資料庫使用多個Slave–>增加Cache (memcache)–>轉到Redis

解決寫的問題:

水平拆分,對錶的拆分,將有的使用者放在這個表,有的使用者放在另外一個表;

可靠性需求

Cache的"雪崩"問題讓人糾結

Cache面臨著快速恢復的挑戰

開發成本需求

Cache和DB的一致性維護成本越來越高(先清理DB, 再清理快取, 不行啊, 太慢了!)

開發需要跟上不斷湧入的產品需求

硬體成本最貴的就是資料庫層面的機器,基本上比前端的機器要貴幾倍,主要是IO密集型,很耗硬體;

維護性複雜

一致性維護成本越來越高;

BerkeleyDB使用B樹,會一直寫新的,內部不會有檔案重新組織;這樣會導致檔案越來越大;大的時候需要進行檔案歸檔,歸檔的操作要定期做;

這樣,就需要有一定的down time;

基於以上考慮, 選擇了Redis

第三:Redis 在新浪微博中的應用

Redis簡介

  1. 支援5種資料結構

支援strings, hashes, lists, sets, sorted sets

string是很好的儲存方式,用來做計數儲存。sets用於建立索引庫非常棒;

  1. K-V 儲存 vs K-V 快取

新浪微博目前使用的98%都是持久化的應用,2%的是快取,用到了600+伺服器

Redis中持久化的應用和非持久化的方式不會差別很大:

非持久化的為8-9萬tps,那麼持久化在7-8萬tps左右;

當使用持久化時,需要考慮到持久化和寫效能的配比,也就是要考慮redis使用的記憶體大小和硬碟寫的速率的比例計算;

  1. 社群活躍

Redis目前有3萬多行程式碼, 程式碼寫的精簡,有很多巧妙的實現,作者有技術潔癖

Redis的社群活躍度很高,這是衡量開源軟體質量的重要指標,開源軟體的初期一般都沒有商業技術服務支援,如果沒有活躍社群做支撐,一旦發生問題都無處求救;

Redis基本原理

redis持久化(aof) append online file:

寫log(aof), 到一定程度再和記憶體合併. 追加再追加, 順序寫磁碟, 對效能影響非常小

  1. 單例項單程序

Redis使用的是單程序,所以在配置時,一個例項只會用到一個CPU;

在配置時,如果需要讓CPU使用率最大化,可以配置Redis例項數對應CPU數, Redis例項數對應埠數(8核Cpu, 8個例項, 8個埠), 以提高併發:

單機測試時, 單條資料在200位元組, 測試的結果為8~9萬tps;

  1. Replication

過程: 資料寫到master–>master儲存到slave的rdb中–>slave載入rdb到記憶體。

儲存點(save point): 當網路中斷了, 連上之後, 繼續傳.

Master-slave下第一次同步是全傳,後面是增量同步;、

  1. 資料一致性

長期執行後多個結點之間存在不一致的可能性;

開發兩個工具程式:

1.對於資料量大的資料,會週期性的全量檢查;

2.實時的檢查增量資料,是否具有一致性;

對於主庫未及時同步從庫導致的不一致,稱之為延時問題;

對於一致性要求不是那麼嚴格的場景,我們只需要要保證最終一致性即可;

對於延時問題,需要根據業務場景特點分析,從應用層面增加策略來解決這個問題;

例如:

1.新註冊的使用者,必須先查詢主庫;

2.註冊成功之後,需要等待3s之後跳轉,後臺此時就是在做資料同步。

第四:分散式快取的架構設計

1.架構設計

由於redis是單點,專案中需要使用,必須自己實現分散式。基本架構圖如下所示:

2.分散式實現

通過key做一致性雜湊,實現key對應redis結點的分佈。

一致性雜湊的實現:

l hash值計算:通過支援MD5與MurmurHash兩種計算方式,預設是採用MurmurHash,高效的hash計算。

l 一致性的實現:通過java的TreeMap來模擬環狀結構,實現均勻分佈

3.client的選擇

對於jedis修改的主要是分割槽模組的修改,使其支援了跟據BufferKey進行分割槽,跟據不同的redis結點資訊,可以初始化不同的 ShardInfo,同時也修改了JedisPool的底層實現,使其連線pool池支援跟據key,value的構造方法,跟據不同 ShardInfos,建立不同的jedis連線客戶端,達到分割槽的效果,供應用層呼叫

4.模組的說明

l 髒資料處理模組,處理失敗執行的快取操作。

l 遮蔽監控模組,對於jedis操作的異常監控,當某結點出現異常可控制redis結點的切除等操作。

整個分散式模組通過hornetq,來切除異常redis結點。對於新結點的增加,也可以通過reload方法實現增加。(此模組對於新增結點也可以很方便實現)

對於以上分散式架構的實現滿足了專案的需求。另外使用中對於一些比較重要用途的快取資料可以單獨設定一些redis結點,設定特定的優先順序。另外對 於快取介面的設計,也可以跟據需求,實現基本介面與一些特殊邏輯介面。對於cas相關操作,以及一些事物操作可以通過其watch機制來實現。

宣告:所有部落格服務於分散式框架,作為框架的技術支援及說明,框架面向企業,是大型網際網路分散式企業架構,後期會介紹linux上部署高可用叢集專案。

相關推薦

教你 redis 實現分散式冪等服務中介軟體

背景 在程式設計領域,冪等性是指對同一個系統,使用同樣的條件,一次請求和重複的多次請求對系統資源的影響是一致的。 在分散式系統裡,client 呼叫 server 提供的服務,由於網路環境的複雜性,呼叫可能有以下幾種情況: server 收到 client 的請求,client 也收到

ASP.NET結合Redis實現分散式快取

  最近一個專案ASP.NET+MySQL 有的網頁開啟初始化的查詢需要10秒甚至更久,使用者體驗極差,而且併發量變大的時候網站容易崩潰 後來想了兩種解決方案都不是太滿意 1、資料庫裡建一張快取表,後臺作業定時去更新這張表,每次網頁開啟就可以直接從快取表裡查詢 2、使用者第一次開啟網站將資

SpringCloud定時任務需要redis實現分散式全域性鎖的相關操作

      我們知道現在微服務很流行,為此,許多中小型企業都將自己以前的框架加以改造,其中以SpringCloud為最多,但是SpringCloud如果要加定時任務的話,在單臺伺服器上很好支援,但是涉及到叢集服務(多臺服務的話)就要用到分散式鎖了,最簡單的方案是用R

如何用Redis實現分散式快取

第一:Redis 是什麼?Redis是基於記憶體、可持久化的日誌型、Key-Value資料庫 高效能儲存系統,並提供多種語言的API.第二:出現背景資料結構(Data Structure)需求越來越多, 但memcache中沒有, 影響開發效率效能需求, 隨著讀操作的量的上升

asp.net mvc Redis實現分散式叢集共享Session

1、這兩天研究Redis搞分散式session問題,網上找的資料都是用ServiceStack.Redis來實現的,但是在做效能測試的時候發現最新的v4版本有限制每小時候最多請求6000次,因為官網開始商業化要收費了,好坑爹的說,還好我前期弄了個性能測試列子,不然上線以後

WEB 應用快取解析以及使用 Redis 實現分散式快取

## 什麼是快取? 快取就是資料交換的緩衝區,用於臨時儲存資料(使用頻繁的資料)。當用戶請求資料時,首先在快取中尋找,如果找到了則直接返回。如果找不到,則去資料庫中查詢。快取的本質就是用空間換時間,犧牲資料的實時性,從而減輕資料庫壓力,儘可能提高吞吐量,有效提升響應速度。 ## 快取的分類 快取

haproxy+redis實現分散式redis伺服器

redis是一個非常強大的nosql服務,不僅能替代memcache這樣的key/value服務,也具有強大的佇列功能,在普通應用上可以替代activemq/rabbitmq一類佇列服務 但是目前為止,redis都沒有實現真正有效的叢集功能,redis的作者承諾會在redi

搭建redis叢集實現分散式快取(一)

redis是一個高階快取,使用到redis作為我們專案的快取,所以就花了一天時間研究了一下redis的一些用法,因為沒轉linux虛擬機器,所以就決定先研究一下windows版本的redis叢集。主要是redis叢集的皮毛:   1.首先下載windows版本的redis:https://github.co

搭建redis叢集實現分散式快取(二)

第一篇那redis的基礎命令都差不多講了一遍了,這篇就將怎麼配置叢集了,最後要達到的效果是一臺主redis,還有幾臺從的redis,每次資料都是同步的,當主redis掛掉了,那麼就會從幾臺從redis挑選出一臺作為主的redis,如果之後剛開始的主redis啟動以後,又會變為剛開始的狀態,   因為要做叢集

Redis實現快取以及快取同步

使用Redis做快取的大體思路是,在相應的資料獲取層,將獲取到的資料儲存一份到Redis中,在下次請求該資料之前,先在Redis中搜索該資料並提取出來,實現快取的快速讀取。 1、傳統開發模式 多次請

redis實現悲觀鎖(後端語言以php為例)

號碼 blank mys 時間 先來 ng-click print -m 兩種 1479 鎖機制 通常使用的鎖分為樂觀鎖,悲觀鎖這兩種,簡單介紹下這兩種鎖,作為本文的背景知識,對這類知識已經有足夠了解的同學可以跳過這部分。 樂觀鎖 先來看下百度百科上的解釋

REDIS實現分布式緩存

最大 內存大小 ctu cto hashes 模塊 歸檔 分享 是否 第一:Redis 是什麽? Redis是基於內存、可持久化的日誌型、Key-Value數據庫 高性能存儲系統,並提供多種語言的API. 第二:出現背景 數據結構(Data Structure)需求越來越多

如何優雅地Redis實現分布式鎖

cal 沒有 cond 發現 指定 finally 描述 sel 現在 https://mp.weixin.qq.com/s?__biz=MzAxNjM2MTk0Ng==&mid=2247484976&idx=2&sn=a0b6771f0b4e471

springboot+redis實現分散式session共享

    官方文件,它是spring session專案的redis相關的一個子文件:https://docs.spring.io/spring-session/docs/2.0.0.BUILD-SNAPSHOT/reference/html5/guides/boot

redis】使用redisTemplate優雅地操作redis及使用redis實現分散式

前言: 上篇已經介紹了redis及如何安裝和叢集redis,這篇介紹如何通過工具優雅地操作redis. Long Long ago,程式猿們還在通過jedis來操作著redis,那時候的猿類,一個個累的沒日沒夜,重複的造著輪子,忙得沒時間陪家人,終於有一天猿類的春天來了,spring家族的r

基於Redis實現分散式

背景 在很多網際網路產品應用中,有些場景需要加鎖處理,比如:秒殺,全域性遞增ID,樓層生成等等。大部分的解決方案是基於DB實現的,Redis為單程序單執行緒模式,採用佇列模式將併發訪問變成序列訪問,且多客戶端對Redis的連線並不存在競爭關係。其次Redis提供一些命令SETNX,GETSET,可以方便

利用Redis實現分散式鎖 使用mysql樂觀鎖解決併發問題

寫在最前面 我在之前總結冪等性的時候,寫過一種分散式鎖的實現,可惜當時沒有真正應用過,著實的心虛啊。正好這段時間對這部分實踐了一下,也算是對之前填坑了。 分散式鎖按照網上的結論,大致分為三種:1、資料庫樂觀鎖; 2、基於Redis的分散式鎖;3.、基於ZooKeeper的分散式鎖; 關於樂觀鎖的實現其實

利用Redis實現分散式

為什麼需要分散式鎖? 在傳統單體應用單機部署的情況下,可以使用Java併發相關的鎖,如ReentrantLcok或synchronized進行互斥控制。但是,隨著業務發展的需要,原單體單機部署的系統,漸漸的被部署在多機器多JVM上同時提供服務,這使得原單機部署情況下的併發控制鎖策略失效了,為了解決這個問

如何用 Redis 實現分散式鎖和超時情況處理

目前各種分散式的架構和微服務架構無處不在,在這種類似架構中處理併發和分散式併發問題,本場 Chat 就主要以 Redis 為例,使用分散式鎖的方式如何處理併發問題和避免超時情況的出現,主要從以下幾個方面講述: Redis 的 Setnx 命令是如何實現分散式鎖的; Setnx 的實現鎖的

mysql實現分散式

       考慮這樣一個場景: 多臺機器同時執行某一任務,要求某一時刻最多隻有一臺機器執行, 該怎麼搞呢? 可以考慮分散式鎖。        思路:在mysql中插入一條記錄,表明獲取鎖。刪除一條記錄,表明釋放