消息隊列是在樂視這邊很是廣泛使用的技術。在咱們部門內部,不一樣的項目使用的消息隊列實現也不同。下面是支付系統的流轉圖(部門兄弟畫的,借用一下):html
從圖中能夠看到,裏面用到了kafka消息隊列。做用是作數據庫分庫分表後的聚合,異步彙總到一張總表。裏面也用到了redis,用來處理高併發下的訂單重複提交。咱們這邊還使用了公司統一集羣的apache qpid消息隊列,是AMQP的一個實現,主要用於不一樣部門間的通訊。通常的大公司都會有一些公司統一的集羣,可是這種統一集羣對開發者來講相對透明,因此部門間相互合做的時候用的多,本身部門內部用,避免採坑,你們寧願本身搭一套。redis用處就更多了。阿里的陽哥本身作了一個異常日誌監控平臺,主要就是用redis作數據傳輸和存儲。java
別人作的東西我就很少說了。下午說說redis在我本身的框架中使用實戰。這是epiphany離線數據的流程圖。epiphany框架源碼地址:https://github.com/xiexiaojing/epiphany。咱們部門內部使用實例地址是:https://github.com/xiexiaojing/epiphany-demo。你們能夠將裏面的DAO部分數據作替換,替換成本身的數據庫隨便什麼數據便可運行。mysql
從圖中能夠看處處理過程基本都是在和redis打交道。Redis的基本數據結構是跳躍表。像這種跟存儲打交道的,數據結構是必需要了解的。好比lucene搜索最初的版本也是用的跳躍表,後來改爲基於圖的有限自動機了。想了解具體瞭解跳躍表能夠看個人另外一篇文章《看Lucene源碼必須知道的基本規則和算法》。像一些java寫的框架,好比dubbo,spring IoC裏,一提到註冊,要註冊到一個地方,在JVM的數據結構通常是hashmap。準確的說:spring IoC裏是經過一個hashmap來持有載入的BeanDefinition對象實現註冊的。linux
Redis持久化原理git
Redis提供了兩種方式對數據進行持久化,分別是RDB(Redis DataBase)和AOF(APPEND ONLY FILE)。RDB持久化方式可以在指定的時間間隔對數據進行快照存儲。AOF持久化方式記錄每次服務器寫的操做,當服務器重啓的時候會從新執行這些命令來恢復原始的數據,AOF命令以redis協議追加保存每次寫操做到文件末尾。Redis還能對AOF文件進行後臺重寫,使得AOF文件的體積不至於過大。不過,我問過不少部門,出於性能考慮,他們的持久化都是不開啓的。若是同時開啓兩種持久化方式,當redis重啓的時候會優先載入AOF文件來恢復原始的數據,由於在一般狀況下AOF文件保存的數據集要比RDB文件保存的數據集要完整。github
瞭解一下持久化的C語言實現。Redis須要執行RDB的時候,服務器會執行如下操做:redis調用系統函數fork(),建立一個子進程。子進程將數據集寫入到一個臨時RDB文件中。當子進程完成對臨時RDB文件的寫入時,redis用新的臨時RDB文件替換原來的RDB文件,並刪除舊RDB文件。在執行fork時linux操做系統(通常大公司的服務器都是這個系統)會使用寫時複製(copy-on-write)策略,即fork函數發生的一刻父子進程共享同一內存數據,當父進程要更新其中某片數據時,操做系統會將該片數據複製一份以保證子進程的數據不收影響,因此新的RDB文件存儲的是之執行fork那一刻的內存數據。RDB文件是通過壓縮的二進制格式,因此佔用的空間會小於內存的數據大小。可是壓縮操做很佔CPU,因此能夠經過配置文件配置禁止壓縮。redis
瞭解一下對應的redis命令。除了自動快照,還能夠手動發送save或者bgsave命令讓redis直行快照。save命令是在主進程上進行的,會阻塞其餘請求。後者會fork子進程進行快照操做。算法
和mysql存儲比較。RDB方式比較相似於mysql的mysqldump命令備份。而AOF更接近於binlog。spring
Redis內存優化sql
redis配置文件中有個maxmemory參數設置,若是沒有設置會繼續分配內存,所以能夠逐漸吃掉全部可用內存。所以,一般建議配置一些限制和策略。這樣作的優勢是:不會致使由於內存飢餓而整機死亡。缺點是:Redis可能會返回內存不足的錯誤寫命令。redis有6種過時策略。
1>volatile-lru:只對設置了過時時間的key進行LRU
2>allkeys-lur:對全部的key進行LRU
3>volatile-random:隨機刪除即將過時的key
4>allkeys-random:從全部的key中隨時刪除
5>volatile-ttl:刪除即將過時的,ttl(tiime to live)剩餘生存時間
6>noeviction:永不過時,返回錯誤
參數的設置能夠採用命令方式,也能夠採用配置文件方式(全部的配置都支持這兩種),配置命令如
config set maxmemory-policy volatile-lru
還能夠設置隨機抽樣數,如
config set maxmemory-samples 5 就是說每次進行淘汰的時候,會隨機抽取5個key從裏面淘汰最不常用的。
redis壓縮列表(ziplist)。壓縮列表是列表鍵和哈希鍵的底層實現之一。當一個列表鍵只包含少許表項,而且每一個列表要麼是小整數,要麼是較短的字符串,那麼redis就會使用壓縮列表來做爲列表鍵的底層實現。當一個哈席鍵只包含少許key-value對,且每一個key和value要麼是小整數,要麼是較短字符串,那麼redis就會使用ziplist做爲哈希鍵的底層實現。
我在介紹本身的epiphany框架的時候(在上面流程圖裏也有體現),若是一個key裏的結構是個hash,在小於1k的hash鍵的狀況下我直接用hash,而大於1k,考慮到寫入性能差,我就直接將hash打包壓縮成一個大value來存儲。考慮使用這兩種策略的其中一個緣由是小散列表使用的內存很是小,節省存儲空間。
跑題時間:
這幅畫的名字叫《洗盡鉛華》