當前位置:首頁 » 算力簡介 » 去中心化研究實驗室dedis

去中心化研究實驗室dedis

發布時間: 2021-07-25 13:26:33

❶ redis和memcached的區別

Redis與Memcached的區別

傳統MySQL+ Memcached架構遇到的問題
實際MySQL是適合進行海量數據存儲的,通過Memcached將熱點數據載入到cache,加速訪問,很多公司都曾經使用過這樣的架構,但隨著業務數據量的不斷增加,和訪問量的持續增長,我們遇到了很多問題:
1.MySQL需要不斷進行拆庫拆表,Memcached也需不斷跟著擴容,擴容和維護工作占據大量開發時間。
2.Memcached與MySQL資料庫數據一致性問題。
3.Memcached數據命中率低或down機,大量訪問直接穿透到DB,MySQL無法支撐。
4.跨機房cache同步問題。
眾多NoSQL百花齊放,如何選擇
最近幾年,業界不斷涌現出很多各種各樣的NoSQL產品,那麼如何才能正確地使用好這些產品,最大化地發揮其長處,是我們需要深入研究和思考的問題,實際歸根結底最重要的是了解這些產品的定位,並且了解到每款產品的tradeoffs,在實際應用中做到揚長避短,總體上這些NoSQL主要用於解決以下幾種問題
1.少量數據存儲,高速讀寫訪問。此類產品通過數據全部in-momery 的方式來保證高速訪問,同時提供數據落地的功能,實際這正是Redis最主要的適用場景。
2.海量數據存儲,分布式系統支持,數據一致性保證,方便的集群節點添加/刪除。
3.這方面最具代表性的是dynamo和bigtable 2篇論文所闡述的思路。前者是一個完全無中心的設計,節點之間通過gossip方式傳遞集群信息,數據保證最終一致性,後者是一個中心化的方案設計,通過類似一個分布式鎖服務來保證強一致性,數據寫入先寫內存和redo log,然後定期compat歸並到磁碟上,將隨機寫優化為順序寫,提高寫入性能。
4.Schema free,auto-sharding等。比如目前常見的一些文檔資料庫都是支持schema-free的,直接存儲json格式數據,並且支持auto-sharding等功能,比如mongodb。
面對這些不同類型的NoSQL產品,我們需要根據我們的業務場景選擇最合適的產品。
Redis適用場景,如何正確的使用
前面已經分析過,Redis最適合所有數據in-momory的場景,雖然Redis也提供持久化功能,但實際更多的是一個disk-backed的功能,跟傳統意義上的持久化有比較大的差別,那麼可能大家就會有疑問,似乎Redis更像一個加強版的Memcached,那麼何時使用Memcached,何時使用Redis呢?

如果簡單地比較Redis與Memcached的區別,大多數都會得到以下觀點:

1 Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
2 Redis支持數據的備份,即master-slave模式的數據備份。
3 Redis支持數據的持久化,可以將內存中的數據保持在磁碟中,重啟的時候可以再次載入進行使用。

拋開這些,可以深入到Redis內部構造去觀察更加本質的區別,理解Redis的設計。

在Redis中,並不是所有的數據都一直存儲在內存中的。這是和Memcached相比一個最大的區別。Redis只會緩存所有的 key的信息,如果Redis發現內存的使用量超過了某一個閥值,將觸發swap的操作,Redis根據「swappability = age*log(size_in_memory)」計 算出哪些key對應的value需要swap到磁碟。然後再將這些key對應的value持久化到磁碟中,同時在內存中清除。這種特性使得Redis可以 保持超過其機器本身內存大小的數據。當然,機器本身的內存必須要能夠保持所有的key,畢竟這些數據是不會進行swap操作的。同時由於Redis將內存 中的數據swap到磁碟中的時候,提供服務的主線程和進行swap操作的子線程會共享這部分內存,所以如果更新需要swap的數據,Redis將阻塞這個 操作,直到子線程完成swap操作後才可以進行修改。

使用Redis特有內存模型前後的情況對比:
VM off: 300k keys, 4096 bytes values: 1.3G used
VM on: 300k keys, 4096 bytes values: 73M used
VM off: 1 million keys, 256 bytes values: 430.12M used
VM on: 1 million keys, 256 bytes values: 160.09M used
VM on: 1 million keys, values as large as you want, still: 160.09M used

當 從Redis中讀取數據的時候,如果讀取的key對應的value不在內存中,那麼Redis就需要從swap文件中載入相應數據,然後再返回給請求方。 這里就存在一個I/O線程池的問題。在默認的情況下,Redis會出現阻塞,即完成所有的swap文件載入後才會相應。這種策略在客戶端的數量較小,進行 批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程序中,這顯然是無法滿足大並發的情況的。所以Redis運行我們設置I/O線程 池的大小,對需要從swap文件中載入相應數據的讀取請求進行並發操作,減少阻塞的時間。

如果希望在海量數據的環境中使用好Redis,我相信理解Redis的內存設計和阻塞的情況是不可缺少的。

❷ php面試題 memcache和redis的區別

Redis與Memcached的區別傳統MySQL+ Memcached架構遇到的問題實際MySQL是適合進行海量數據存儲的,通過Memcached將熱點數據載入到cache,加速訪問,很多公司都曾經使用過這樣的架構,但隨著業務數據量的不斷增加,和訪問量的持續增長,我們遇到了很多問題:1.MySQL需要不斷進行拆庫拆表,Memcached也需不斷跟著擴容,擴容和維護工作占據大量開發時間。2.Memcached與MySQL資料庫數據一致性問題。3.Memcached數據命中率低或down機,大量訪問直接穿透到DB,MySQL無法支撐。4.跨機房cache同步問題。眾多NoSQL百花齊放,如何選擇最近幾年,業界不斷涌現出很多各種各樣的NoSQL產品,那麼如何才能正確地使用好這些產品,最大化地發揮其長處,是我們需要深入研究和思考的問題,實際歸根結底最重要的是了解這些產品的定位,並且了解到每款產品的tradeoffs,在實際應用中做到揚長避短,總體上這些NoSQL主要用於解決以下幾種問題1.少量數據存儲,高速讀寫訪問。此類產品通過數據全部in-momery 的方式來保證高速訪問,同時提供數據落地的功能,實際這正是Redis最主要的適用場景。2.海量數據存儲,分布式系統支持,數據一致性保證,方便的集群節點添加/刪除。3.這方面最具代表性的是dynamo和bigtable 2篇論文所闡述的思路。前者是一個完全無中心的設計,節點之間通過gossip方式傳遞集群信息,數據保證最終一致性,後者是一個中心化的方案設計,通過類似一個分布式鎖服務來保證強一致性,數據寫入先寫內存和redo log,然後定期compat歸並到磁碟上,將隨機寫優化為順序寫,提高寫入性能。4.Schema free,auto-sharding等。比如目前常見的一些文檔資料庫都是支持schema-free的,直接存儲json格式數據,並且支持auto-sharding等功能,比如mongodb。面對這些不同類型的NoSQL產品,我們需要根據我們的業務場景選擇最合適的產品。Redis適用場景,如何正確的使用前面已經分析過,Redis最適合所有數據in-momory的場景,雖然Redis也提供持久化功能,但實際更多的是一個disk-backed的功能,跟傳統意義上的持久化有比較大的差別,那麼可能大家就會有疑問,似乎Redis更像一個加強版的Memcached,那麼何時使用Memcached,何時使用Redis呢?如果簡單地比較Redis與Memcached的區別,大多數都會得到以下觀點:1 Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。2 Redis支持數據的備份,即master-slave模式的數據備份。3 Redis支持數據的持久化,可以將內存中的數據保持在磁碟中,重啟的時候可以再次載入進行使用。拋開這些,可以深入到Redis內部構造去觀察更加本質的區別,理解Redis的設計。在Redis中,並不是所有的數據都一直存儲在內存中的。這是和Memcached相比一個最大的區別。Redis只會緩存所有的 key的信息,如果Redis發現內存的使用量超過了某一個閥值,將觸發swap的操作,Redis根據「swappability = age*log(size_in_memory)」計 算出哪些key對應的value需要swap到磁碟。然後再將這些key對應的value持久化到磁碟中,同時在內存中清除。這種特性使得Redis可以 保持超過其機器本身內存大小的數據。當然,機器本身的內存必須要能夠保持所有的key,畢竟這些數據是不會進行swap操作的。同時由於Redis將內存 中的數據swap到磁碟中的時候,提供服務的主線程和進行swap操作的子線程會共享這部分內存,所以如果更新需要swap的數據,Redis將阻塞這個 操作,直到子線程完成swap操作後才可以進行修改。使用Redis特有內存模型前後的情況對比:VM off: 300k keys, 4096 bytes values: 1.3G usedVM on: 300k keys, 4096 bytes values: 73M usedVM off: 1 million keys, 256 bytes values: 430.12M usedVM on: 1 million keys, 256 bytes values: 160.09M usedVM on: 1 million keys, values as large as you want, still: 160.09M used當 從Redis中讀取數據的時候,如果讀取的key對應的value不在內存中,那麼Redis就需要從swap文件中載入相應數據,然後再返回給請求方。 這里就存在一個I/O線程池的問題。在默認的情況下,Redis會出現阻塞,即完成所有的swap文件載入後才會相應。這種策略在客戶端的數量較小,進行 批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程序中,這顯然是無法滿足大並發的情況的。所以Redis運行我們設置I/O線程 池的大小,對需要從swap文件中載入相應數據的讀取請求進行並發操作,減少阻塞的時間。如果希望在海量數據的環境中使用好Redis,我相信理解Redis的內存設計和阻塞的情況是不可缺少的。補充的知識點:memcached和redis的比較1 網路IO模型Memcached是多線程,非阻塞IO復用的網路模型,分為監聽主線程和worker子線程,監聽線程監聽網路連接,接受請求後,將連接描述字pipe 傳遞給worker線程,進行讀寫IO, 網路層使用libevent封裝的事件庫,多線程模型可以發揮多核作用,但是引入了cache coherency和鎖的問題,比如,Memcached最常用的stats 命令,實際Memcached所有操作都要對這個全局變數加鎖,進行計數等工作,帶來了性能損耗。(Memcached網路IO模型)Redis使用單線程的IO復用模型,自己封裝了一個簡單的AeEvent事件處理框架,主要實現了epoll、kqueue和select,對於單純只有IO操作來說,單線程可以將速度優勢發揮到最大,但是Redis也提供了一些簡單的計算功能,比如排序、聚合等,對於這些操作,單線程模型實際會嚴重影響整體吞吐量,CPU計算過程中,整個IO調度都是被阻塞住的。2.內存管理方面Memcached使用預分配的內存池的方式,使用slab和大小不同的chunk來管理內存,Item根據大小選擇合適的chunk存儲,內存池的方式可以省去申請/釋放內存的開銷,並且能減小內存碎片產生,但這種方式也會帶來一定程度上的空間浪費,並且在內存仍然有很大空間時,新的數據也可能會被剔除,原因可以參考Timyang的文章:/memcached/)。Memcached的客戶端軟體實現非常多,包括C/C++, PHP, Java, Python, Ruby, Perl, Erlang, Lua等。當前Memcached使用廣泛,除了LiveJournal以外還有Wikipedia、Flickr、Twitter、Youtube和WordPress等。在Window系統下,Memcached的安裝非常方便,只需從以上給出的地址下載可執行軟體然後運行memcached.exe –d install即可完成安裝。在Linux等系統下,我們首先需要安裝libevent,然後從獲取源碼,make && make install即可。默認情況下,Memcached的伺服器啟動程序會安裝到/usr/local/bin目錄下。在啟動Memcached時,我們可以為其配置不同的啟動參數。1.1 Memcache配置Memcached伺服器在啟動時需要對關鍵的參數進行配置,下面我們就看一看Memcached在啟動時需要設定哪些關鍵參數以及這些參數的作用。1)-p Memcached的TCP監聽埠,預設配置為11211;2)-U Memcached的UDP監聽埠,預設配置為11211,為0時表示關閉UDP監聽;3)-s Memcached監聽的UNIX套接字路徑;4)-a 訪問UNIX套接字的八進制掩碼,預設配置為0700;5)-l 監聽的伺服器IP地址,默認為所有網卡;6)-d 為Memcached伺服器啟動守護進程;7)-r 最大core文件大小;8)-u 運行Memcached的用戶,如果當前為root的話需要使用此參數指定用戶;9)-m 分配給Memcached使用的內存數量,單位是MB;10)-M 指示Memcached在內存用光的時候返回錯誤而不是使用LRU演算法移除數據記錄;11)-c 最大並發連數,預設配置為1024;12)-v –vv –vvv 設定伺服器端列印的消息的詳細程度,其中-v僅列印錯誤和警告信息,-vv在-v的基礎上還會列印客戶端的命令和相應,-vvv在-vv的基礎上還會列印內存狀態轉換信息;13)-f 用於設置chunk大小的遞增因子;14)-n 最小的chunk大小,預設配置為48個位元組;15)-t Memcached伺服器使用的線程數,預設配置為4個;16)-L 嘗試使用大內存頁;17)-R 每個事件的最大請求數,預設配置為20個;18)-C 禁用CAS,CAS模式會帶來8個位元組的冗餘;2. Redis簡介Redis是一個開源的key-value存儲系統。與Memcached類似,Redis將大部分數據存儲在內存中,支持的數據類型包括:字元串、哈希表、鏈表、集合、有序集合以及基於這些數據類型的相關操作。Redis使用C語言開發,在大多數像Linux、BSD和Solaris等POSIX系統上無需任何外部依賴就可以使用。Redis支持的客戶端語言也非常豐富,常用的計算機語言如C、C#、C++、Object-C、PHP、Python、Java、Perl、Lua、Erlang等均有可用的客戶端來訪問Redis伺服器。當前Redis的應用已經非常廣泛,國內像新浪、淘寶,國外像Flickr、Github等均在使用Redis的緩存服務。Redis的安裝非常方便,只需從bin目錄下。在啟動Redis伺服器時,我們需要為其指定一個配置文件,預設情況下配置文件在Redis的源碼目錄下,文件名為redis.conf。php面試題 memcache和redis的區別

❸ redis集群中master和salve是怎麼設置的

redis cluster在設計的時候,就考慮到了去中心化,去中間件,也就是說,集群中的每個節點都是平等的關系,都是對等的,每個節點都保存各自的數據和整個集群的狀態。
每個節點都和其他所有節點連接,而且這些連接保持活躍,這樣就保證了我們只需要連接集群中的任意一個節點,就可以獲取到其他節點的數據。

❹ Redis和Memcached的區別

Redis與Memcached的區別

傳統MySQL+ Memcached架構遇到的問題
實際MySQL是適合進行海量數據存儲的,通過Memcached將熱點數據載入到cache,加速訪問,很多公司都曾經使用過這樣的架構,但隨著業務數據量的不斷增加,和訪問量的持續增長,我們遇到了很多問題:
1.MySQL需要不斷進行拆庫拆表,Memcached也需不斷跟著擴容,擴容和維護工作占據大量開發時間。
2.Memcached與MySQL資料庫數據一致性問題。
3.Memcached數據命中率低或down機,大量訪問直接穿透到DB,MySQL無法支撐。
4.跨機房cache同步問題。
眾多NoSQL百花齊放,如何選擇
最近幾年,業界不斷涌現出很多各種各樣的NoSQL產品,那麼如何才能正確地使用好這些產品,最大化地發揮其長處,是我們需要深入研究和思考的問題,實際歸根結底最重要的是了解這些產品的定位,並且了解到每款產品的tradeoffs,在實際應用中做到揚長避短,總體上這些NoSQL主要用於解決以下幾種問題
1.少量數據存儲,高速讀寫訪問。此類產品通過數據全部in-momery 的方式來保證高速訪問,同時提供數據落地的功能,實際這正是Redis最主要的適用場景。
2.海量數據存儲,分布式系統支持,數據一致性保證,方便的集群節點添加/刪除。
3.這方面最具代表性的是dynamo和bigtable 2篇論文所闡述的思路。前者是一個完全無中心的設計,節點之間通過gossip方式傳遞集群信息,數據保證最終一致性,後者是一個中心化的方案設計,通過類似一個分布式鎖服務來保證強一致性,數據寫入先寫內存和redo log,然後定期compat歸並到磁碟上,將隨機寫優化為順序寫,提高寫入性能。
4.Schema free,auto-sharding等。比如目前常見的一些文檔資料庫都是支持schema-free的,直接存儲json格式數據,並且支持auto-sharding等功能,比如mongodb。
面對這些不同類型的NoSQL產品,我們需要根據我們的業務場景選擇最合適的產品。
Redis適用場景,如何正確的使用
前面已經分析過,Redis最適合所有數據in-momory的場景,雖然Redis也提供持久化功能,但實際更多的是一個disk-backed的功能,跟傳統意義上的持久化有比較大的差別,那麼可能大家就會有疑問,似乎Redis更像一個加強版的Memcached,那麼何時使用Memcached,何時使用Redis呢?

如果簡單地比較Redis與Memcached的區別,大多數都會得到以下觀點:

1 Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。

2 Redis支持數據的備份,即master-slave模式的數據備份。

3 Redis支持數據的持久化,可以將內存中的數據保持在磁碟中,重啟的時候可以再次載入進行使用。

拋開這些,可以深入到Redis內部構造去觀察更加本質的區別,理解Redis的設計。

在Redis中,並不是所有的數據都一直存儲在內存中的。這是和Memcached相比一個最大的區別。Redis只會緩存所有的 key的信息,如果Redis發現內存的使用量超過了某一個閥值,將觸發swap的操作,Redis根據「swappability = age*log(size_in_memory)」計 算出哪些key對應的value需要swap到磁碟。然後再將這些key對應的value持久化到磁碟中,同時在內存中清除。這種特性使得Redis可以 保持超過其機器本身內存大小的數據。當然,機器本身的內存必須要能夠保持所有的key,畢竟這些數據是不會進行swap操作的。同時由於Redis將內存 中的數據swap到磁碟中的時候,提供服務的主線程和進行swap操作的子線程會共享這部分內存,所以如果更新需要swap的數據,Redis將阻塞這個 操作,直到子線程完成swap操作後才可以進行修改。

使用Redis特有內存模型前後的情況對比:
VM off: 300k keys, 4096 bytes values: 1.3G used
VM on: 300k keys, 4096 bytes values: 73M used
VM off: 1 million keys, 256 bytes values: 430.12M used
VM on: 1 million keys, 256 bytes values: 160.09M used
VM on: 1 million keys, values as large as you want, still: 160.09M used

當 從Redis中讀取數據的時候,如果讀取的key對應的value不在內存中,那麼Redis就需要從swap文件中載入相應數據,然後再返回給請求方。 這里就存在一個I/O線程池的問題。在默認的情況下,Redis會出現阻塞,即完成所有的swap文件載入後才會相應。這種策略在客戶端的數量較小,進行 批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程序中,這顯然是無法滿足大並發的情況的。所以Redis運行我們設置I/O線程 池的大小,對需要從swap文件中載入相應數據的讀取請求進行並發操作,減少阻塞的時間。

如果希望在海量數據的環境中使用好Redis,我相信理解Redis的內存設計和阻塞的情況是不可缺少的。

補充的知識點:
memcached和redis的比較
1 網路IO模型
Memcached是多線程,非阻塞IO復用的網路模型,分為監聽主線程和worker子線程,監聽線程監聽網路連接,接受請求後,將連接描述字pipe 傳遞給worker線程,進行讀寫IO, 網路層使用libevent封裝的事件庫,多線程模型可以發揮多核作用,但是引入了cache coherency和鎖的問題,比如,Memcached最常用的stats 命令,實際Memcached所有操作都要對這個全局變數加鎖,進行計數等工作,帶來了性能損耗。

(Memcached網路IO模型)
Redis使用單線程的IO復用模型,自己封裝了一個簡單的AeEvent事件處理框架,主要實現了epoll、kqueue和select,對於單純只有IO操作來說,單線程可以將速度優勢發揮到最大,但是Redis也提供了一些簡單的計算功能,比如排序、聚合等,對於這些操作,單線程模型實際會嚴重影響整體吞吐量,CPU計算過程中,整個IO調度都是被阻塞住的。
2.內存管理方面
Memcached使用預分配的內存池的方式,使用slab和大小不同的chunk來管理內存,Item根據大小選擇合適的chunk存儲,內存池的方式可以省去申請/釋放內存的開銷,並且能減小內存碎片產生,但這種方式也會帶來一定程度上的空間浪費,並且在內存仍然有很大空間時,新的數據也可能會被剔除,原因可以參考Timyang的文章:http://timyang.net/data/Memcached-lru-evictions/
Redis使用現場申請內存的方式來存儲數據,並且很少使用free-list等方式來優化內存分配,會在一定程度上存在內存碎片,Redis跟據存儲命令參數,會把帶過期時間的數據單獨存放在一起,並把它們稱為臨時數據,非臨時數據是永遠不會被剔除的,即便物理內存不夠,導致swap也不會剔除任何非臨時數據(但會嘗試剔除部分臨時數據),這點上Redis更適合作為存儲而不是cache。
3.數據一致性問題
Memcached提供了cas命令,可以保證多個並發訪問操作同一份數據的一致性問題。 Redis沒有提供cas 命令,並不能保證這點,不過Redis提供了事務的功能,可以保證一串 命令的原子性,中間不會被任何操作打斷。
4.存儲方式及其它方面
Memcached基本只支持簡單的key-value存儲,不支持枚舉,不支持持久化和復制等功能
Redis除key/value之外,還支持list,set,sorted set,hash等眾多數據結構,提供了KEYS
進行枚舉操作,但不能在線上使用,如果需要枚舉線上數據,Redis提供了工具可以直接掃描其mp文件,枚舉出所有數據,Redis還同時提供了持久化和復制等功能。
5.關於不同語言的客戶端支持
在不同語言的客戶端方面,Memcached和Redis都有豐富的第三方客戶端可供選擇,不過因為Memcached發展的時間更久一些,目前看在客戶端支持方面,Memcached的很多客戶端更加成熟穩定,而Redis由於其協議本身就比Memcached復雜,加上作者不斷增加新的功能等,對應第三方客戶端跟進速度可能會趕不上,有時可能需要自己在第三方客戶端基礎上做些修改才能更好的使用。
根據以上比較不難看出,當我們不希望數據被踢出,或者需要除key/value之外的更多數據類型時,或者需要落地功能時,使用Redis比使用Memcached更合適。
關於Redis的一些周邊功能
Redis除了作為存儲之外還提供了一些其它方面的功能,比如聚合計算、pubsub、scripting等,對於此類功能需要了解其實現原理,清楚地了解到它的局限性後,才能正確的使用,比如pubsub功能,這個實際是沒有任何持久化支持的,消費方連接閃斷或重連之間過來的消息是會全部丟失的,又比如聚合計算和scripting等功能受Redis單線程模型所限,是不可能達到很高的吞吐量的,需要謹慎使用。
總的來說Redis作者是一位非常勤奮的開發者,可以經常看到作者在嘗試著各種不同的新鮮想法和思路,針對這些方面的功能就要求我們需要深入了解後再使用。
總結:
1.Redis使用最佳方式是全部數據in-memory。
2.Redis更多場景是作為Memcached的替代者來使用。
3.當需要除key/value之外的更多數據類型支持時,使用Redis更合適。
4.當存儲的數據不能被剔除時,使用Redis更合適。

❺ 數據更新後redis怎麼設置超時

Redis在分布式應用中占據著越來越重要的地位,短短的幾萬行代碼,實現了一個高性能的數據存儲服務。最近mp中心的cm8集群出現過幾次redis超時的情況,但是查看redis機器的相關內存都沒有發現內存不夠,或者內存發生交換的情況,查看redis源碼之後,發現在某些情況下redis會出現超時的狀況,相關細節如下。
1. 網路。Redis的處理與網路息息相關,如果網路出現閃斷則容易發生redis超時的狀況。如果出現這種狀況首先應查看redis機器網路帶寬信息,判斷是否有閃斷情況發生。
2. 內存。redis所有的數據都放在內存里,當物理內存不夠時,linux os會使用swap內存,導致內存交換發生,這時如果有redis調用命令就會產生redis超時。這里可以通過調整/proc/sys/vm/swappiness參數,來設置物理內存使用超過多少就會進行swap。
int rdbSaveBackground(char *filename) { pid_t childpid; long long start; if (server.rdb_child_pid != -1) return REDIS_ERR; serverserver.dirty_before_bgsave = server.dirty; server.lastbgsave_try = time(NULL); start = ustime(); if ((childpid = fork()) == 0) { int retval; /* Child */ if (server.ipfd > 0) close(server.ipfd); if (server.sofd > 0) close(server.sofd); retval = rdbSave(filename); if (retval == REDIS_OK) { size_t private_dirty = zmalloc_get_private_dirty(); if (private_dirty) { redisLog(REDIS_NOTICE, "RDB: %zu MB of memory used by -on-write", private_dirty/(1024*1024)); } } exitFromChild((retval == REDIS_OK) ? 0 : 1); } else { /* Parent */ server.stat_fork_time = ustime()-start; if (childpid == -1) { server.lastbgsave_status = REDIS_ERR; redisLog(REDIS_WARNING,"Can't save in background: fork: %s", strerror(errno)); return REDIS_ERR; } redisLog(REDIS_NOTICE,"Background saving started by pid %d",childpid); server.rdb_save_time_start = time(NULL); server.rdb_child_pid = childpid; updateDictResizePolicy(); return REDIS_OK; } return REDIS_OK; /* unreached */ }

程序1
另外還有一些特殊情況也會導致swap發生。當我們使用rdb做為redis集群持久化時可能會發生物理內存不夠的情況(aof持久化只是保持支持不斷的追加redis集群變化操作,不太容易引起swap)。當使用rdb持久化時,如程序1所示主進程會fork一個子進程去mp redis中所有的數據,主進程依然為客戶端服務。此時主進程和子進程共享同一塊內存區域, linux內核採用寫時復制來保證數據的安全性。在這種模式下如果客戶端發來寫請求,內核將該頁賦值到一個新的頁面上並標記為寫,在將寫請求寫入該頁面。因此,在rdb持久化時,如果有其他請求,那麼redis會使用更多的內存,更容易發生swap,因此在可以快速恢復的場景下盡量少使用rdb持久化可以將rdb mp的條件設的苛刻一點,當然也可以選擇aof,但是aof也有他自身的缺點。另外也可以使用2.6以後的主從結構,將讀寫分離,這樣不會出現server進程上又讀又寫的情景發生 3. Redis單進程處理命令。Redis支持udp和tcp兩種連接,redis客戶端向redis伺服器發送包含redis命令的信息,redis伺服器收到信息後解析命令後執行相應的操作,redis處理命令是串列的具體流程如下。首先服務端建立連接如程序2所示,在創建socket,bind,listen後返迴文件描述符:

server.ipfd = anetTcpServer(server.neterr,server.port,server.bindaddr);

程序2
對於redis這種服務來說,它需要處理成千上萬個連接(最高達到655350),需要使用多路復用來處理多個連接。這里redis提供了epoll,select, kqueue來實現,這里在默認使用epoll(ae.c)。拿到listen函數返回的文件描述符fd後,redis將fd和其處理acceptTcpHandler函數加入到事件驅動的鏈表中.實際上在加入事件隊列中,程序4事件驅動程序將套接字相關的fd文件描述符加入到epoll的監聽事件中。
if (server.ipfd > 0 && aeCreateFileEvent(server.el,server.ipfd,AE_READABLE, acceptTcpHandler,NULL) == AE_ERR) redisPanic("Unrecoverable error creating server.ipfd file event."); int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData) { if (fd >= eventLoop->setsize) { errno = ERANGE; return AE_ERR; } aeFileEvent *fe = &eventLoop->events[fd]; if (aeApiAddEvent(eventLoop, fd, mask) == -1) return AE_ERR; fe->mask |= mask; if (mask & AE_READABLE) fe->rfileProc = proc; if (mask & AE_WRITABLE) fe->wfileProc = proc; fe->clientDataclientData = clientData; if (fd > eventLoop->maxfd) eventLoop->maxfd = fd; return AE_OK; }

程序3

static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { aeApiState *state = eventLoop->apidata; struct epoll_event ee; /* If the fd was already monitored for some event, we need a MOD * operation. Otherwise we need an ADD operation. */ int op = eventLoop->events[fd].mask == AE_NONE ? EPOLL_CTL_ADD : EPOLL_CTL_MOD; ee.events = 0; mask |= eventLoop->events[fd].mask; /* Merge old events */ if (mask & AE_READABLE) ee.events |= EPOLLIN; if (mask & AE_WRITABLE) ee.events |= EPOLLOUT; ee.data.u64 = 0; /* avoid valgrind warning */ ee.data.fd = fd; if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1; return 0; }

程序4
在初始話完所有事件驅動後,如程序5所示主進程根據numevents = aeApiPoll(eventLoop, tvp)獲得io就緒的文件描述符和其對應的處理程序,並對fd進行處理。大致流程是accept()->createclient()->readQueryFromClient()。其中readQueryFromClient()讀取信息中的redis命令-> processInputBuffer()->call()最後完成命令。
void aeMain(aeEventLoop *eventLoop) { eventLoop->stop = 0; while (!eventLoop->stop) { if (eventLoop->beforesleep != NULL) eventLoop->beforesleep(eventLoop); aeProcessEvents(eventLoop, AE_ALL_EVENTS); } } int aeProcessEvents(aeEventLoop *eventLoop, int flags) {------------------------------- numevents = aeApiPoll(eventLoop, tvp); for (j = 0; j < numevents; j++) { aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd]; int mask = eventLoop->fired[j].mask; int fd = eventLoop->fired[j].fd; int rfired = 0; /* note the fe->mask & mask & ... code: maybe an already processed * event removed an element that fired and we still didn't * processed, so we check if the event is still valid. */ if (fe->mask & mask & AE_READABLE) { rfired = 1; fe->rfileProc(eventLoop,fd,fe->clientData,mask); } if (fe->mask & mask & AE_WRITABLE) { if (!rfired || fe->wfileProc != fe->rfileProc) fe->wfileProc(eventLoop,fd,fe->clientData,mask); } processed++; } }

程序5
從上述代碼可以看出redis利用ae事件驅動結合epoll多路復用實現了串列式的命令處理。所以一些慢命令例如sort,hgetall,union,mget都會使得單命令處理時間較長,容易引起後續命令time out.所以我們第一需要從業務上盡量避免使用慢命令,如將hash格式改為kv自行解析,第二增加redis實例個數,每個redis伺服器調用盡量少的慢命令。

❻ 如何利用Redis擴展數據服務,實現分片及高可用

應用Redis實現數據的讀寫,同時利用隊列處理器定時將數據寫入mysql。同時要注意避免沖突,在redis啟動時去mysql讀取所有表鍵值存入redis中,往redis寫數據時,對redis主鍵自增並進行讀取,若mysql更新失敗,則需要及時清除緩存及同步redis主鍵。這樣處理,主要是實時讀寫redis,而mysql數據則通過隊列非同步處理,緩解mysql壓力,不過這種方法應用場景主要基於高並發,而且redis的高可用集群架構相對更復雜,一般不是很推薦。

❼ redis做緩存,怎麼更新裡面的數據

偽代碼如下,思路也清晰。
讀寫部分
if(redis){
讀取redis數據
}else{
資料庫讀取,存redis+設置超時時間
}
更新部分
if(資料庫update){
更新redis+設置超時時間
}

❽ php面試題 memcache和redis的區別

Redis與Memcached的區別

傳統MySQL+ Memcached架構遇到的問題

實際MySQL是適合進行海量數據存儲的,通過Memcached將熱點數據載入到cache,加速訪問,很多公司都曾經使用過這樣的架構,但隨著業務數據量的不斷增加,和訪問量的持續增長,我們遇到了很多問題:

1.MySQL需要不斷進行拆庫拆表,Memcached也需不斷跟著擴容,擴容和維護工作占據大量開發時間。

2.Memcached與MySQL資料庫數據一致性問題。

3.Memcached數據命中率低或down機,大量訪問直接穿透到DB,MySQL無法支撐。

4.跨機房cache同步問題。

眾多NoSQL百花齊放,如何選擇

最近幾年,業界不斷涌現出很多各種各樣的NoSQL產品,那麼如何才能正確地使用好這些產品,最大化地發揮其長處,是我們需要深入研究和思考的
問題,實際歸根結底最重要的是了解這些產品的定位,並且了解到每款產品的tradeoffs,在實際應用中做到揚長避短,總體上這些NoSQL主要用於解
決以下幾種問題

1.少量數據存儲,高速讀寫訪問。此類產品通過數據全部in-momery 的方式來保證高速訪問,同時提供數據落地的功能,實際這正是Redis最主要的適用場景。

2.海量數據存儲,分布式系統支持,數據一致性保證,方便的集群節點添加/刪除。

3.這方面最具代表性的是dynamo和bigtable 2篇論文所闡述的思路。前者是一個完全無中心的設計,節點之間通過gossip方式傳遞集群信息,數據保證最終一致性,後者是一個中心化的方案設計,通過類似一個分布式鎖服務來保證強一致性,數據寫入先寫內存和redo log,然後定期compat歸並到磁碟上,將隨機寫優化為順序寫,提高寫入性能。

4.Schema free,auto-sharding等。比如目前常見的一些文檔資料庫都是支持schema-free的,直接存儲json格式數據,並且支持auto-sharding等功能,比如mongodb。

面對這些不同類型的NoSQL產品,我們需要根據我們的業務場景選擇最合適的產品。

Redis適用場景,如何正確的使用

前面已經分析過,Redis最適合所有數據in-momory的場景,雖然Redis也提供持久化功能,但實際更多的是一個disk-
backed的功能,跟傳統意義上的持久化有比較大的差別,那麼可能大家就會有疑問,似乎Redis更像一個加強版的Memcached,那麼何時使用
Memcached,何時使用Redis呢?

如果簡單地比較Redis與Memcached的區別,大多數都會得到以下觀點:

1 Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。

2 Redis支持數據的備份,即master-slave模式的數據備份。

3 Redis支持數據的持久化,可以將內存中的數據保持在磁碟中,重啟的時候可以再次載入進行使用。

拋開這些,可以深入到Redis內部構造去觀察更加本質的區別,理解Redis的設計。


Redis中,並不是所有的數據都一直存儲在內存中的。這是和Memcached相比一個最大的區別。Redis只會緩存所有的
key的信息,如果Redis發現內存的使用量超過了某一個閥值,將觸發swap的操作,Redis根據「swappability =
age*log(size_in_memory)」計
算出哪些key對應的value需要swap到磁碟。然後再將這些key對應的value持久化到磁碟中,同時在內存中清除。這種特性使得Redis可以

保持超過其機器本身內存大小的數據。當然,機器本身的內存必須要能夠保持所有的key,畢竟這些數據是不會進行swap操作的。同時由於Redis將內存

中的數據swap到磁碟中的時候,提供服務的主線程和進行swap操作的子線程會共享這部分內存,所以如果更新需要swap的數據,Redis將阻塞這個
操作,直到子線程完成swap操作後才可以進行修改。

使用Redis特有內存模型前後的情況對比:
VM off: 300k keys, 4096 bytes values: 1.3G used
VM on: 300k keys, 4096 bytes values: 73M used
VM off: 1 million keys, 256 bytes values: 430.12M used
VM on: 1 million keys, 256 bytes values: 160.09M used
VM on: 1 million keys, values as large as you want, still: 160.09M used



從Redis中讀取數據的時候,如果讀取的key對應的value不在內存中,那麼Redis就需要從swap文件中載入相應數據,然後再返回給請求方。

這里就存在一個I/O線程池的問題。在默認的情況下,Redis會出現阻塞,即完成所有的swap文件載入後才會相應。這種策略在客戶端的數量較小,進行

批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程序中,這顯然是無法滿足大並發的情況的。所以Redis運行我們設置I/O線程
池的大小,對需要從swap文件中載入相應數據的讀取請求進行並發操作,減少阻塞的時間。

如果希望在海量數據的環境中使用好Redis,我相信理解Redis的內存設計和阻塞的情況是不可缺少的。

補充的知識點:

memcached和redis的比較

1 網路IO模型

Memcached是多線程,非阻塞IO復用的網路模型,分為監聽主線程和worker子線程,監聽線程監聽網路連接,接受請求後,將連接描述
字pipe 傳遞給worker線程,進行讀寫IO, 網路層使用libevent封裝的事件庫,多線程模型可以發揮多核作用,但是引入了cache
coherency和鎖的問題,比如,Memcached最常用的stats
命令,實際Memcached所有操作都要對這個全局變數加鎖,進行計數等工作,帶來了性能損耗。

(Memcached網路IO模型)

Redis使用單線程的IO復用模型,自己封裝了一個簡單的AeEvent事件處理框架,主要實現了epoll、kqueue和select,
對於單純只有IO操作來說,單線程可以將速度優勢發揮到最大,但是Redis也提供了一些簡單的計算功能,比如排序、聚合等,對於這些操作,單線程模型實
際會嚴重影響整體吞吐量,CPU計算過程中,整個IO調度都是被阻塞住的。

2.內存管理方面

Memcached使用預分配的內存池的方式,使用slab和大小不同的chunk來管理內存,Item根據大小選擇合適的chunk存儲,內
存池的方式可以省去申請/釋放內存的開銷,並且能減小內存碎片產生,但這種方式也會帶來一定程度上的空間浪費,並且在內存仍然有很大空間時,新的數據也可
能會被剔除,原因可以參考Timyang的文章:http://timyang.net/data/Memcached-lru-evictions/

Redis使用現場申請內存的方式來存儲數據,並且很少使用free-list等方式來優化內存分配,會在一定程度上存在內存碎片,Redis
跟據存儲命令參數,會把帶過期時間的數據單獨存放在一起,並把它們稱為臨時數據,非臨時數據是永遠不會被剔除的,即便物理內存不夠,導致swap也不會剔
除任何非臨時數據(但會嘗試剔除部分臨時數據),這點上Redis更適合作為存儲而不是cache。

3.數據一致性問題

Memcached提供了cas命令,可以保證多個並發訪問操作同一份數據的一致性問題。 Redis沒有提供cas 命令,並不能保證這點,不過Redis提供了事務的功能,可以保證一串 命令的原子性,中間不會被任何操作打斷。

4.存儲方式及其它方面

Memcached基本只支持簡單的key-value存儲,不支持枚舉,不支持持久化和復制等功能

Redis除key/value之外,還支持list,set,sorted set,hash等眾多數據結構,提供了KEYS

進行枚舉操作,但不能在線上使用,如果需要枚舉線上數據,Redis提供了工具可以直接掃描其mp文件,枚舉出所有數據,Redis還同時提供了持久化和復制等功能。

5.關於不同語言的客戶端支持

在不同語言的客戶端方面,Memcached和Redis都有豐富的第三方客戶端可供選擇,不過因為Memcached發展的時間更久一些,目
前看在客戶端支持方面,Memcached的很多客戶端更加成熟穩定,而Redis由於其協議本身就比Memcached復雜,加上作者不斷增加新的功能
等,對應第三方客戶端跟進速度可能會趕不上,有時可能需要自己在第三方客戶端基礎上做些修改才能更好的使用。

根據以上比較不難看出,當我們不希望數據被踢出,或者需要除key/value之外的更多數據類型時,或者需要落地功能時,使用Redis比使用Memcached更合適。

關於Redis的一些周邊功能

Redis除了作為存儲之外還提供了一些其它方面的功能,比如聚合計算、pubsub、scripting等,對於此類功能需要了解其實現原
理,清楚地了解到它的局限性後,才能正確的使用,比如pubsub功能,這個實際是沒有任何持久化支持的,消費方連接閃斷或重連之間過來的消息是會全部丟
失的,又比如聚合計算和scripting等功能受Redis單線程模型所限,是不可能達到很高的吞吐量的,需要謹慎使用。

總的來說Redis作者是一位非常勤奮的開發者,可以經常看到作者在嘗試著各種不同的新鮮想法和思路,針對這些方面的功能就要求我們需要深入了解後再使用。

總結:

1.Redis使用最佳方式是全部數據in-memory。

2.Redis更多場景是作為Memcached的替代者來使用。

3.當需要除key/value之外的更多數據類型支持時,使用Redis更合適。

4.當存儲的數據不能被剔除時,使用Redis更合適。

談談Memcached與Redis(一)

1. Memcached簡介

Memcached是以LiveJurnal旗下Danga Interactive公司的Bard
Fitzpatric為首開發的高性能分布式內存緩存伺服器。其本質上就是一個內存key-value資料庫,但是不支持數據的持久化,伺服器關閉之後數
據全部丟失。Memcached使用C語言開發,在大多數像Linux、BSD和Solaris等POSIX系統上,只要安裝了libevent即可使
用。在Windows下,它也有一個可用的非官方版本(http://code.jellycan.com/memcached/)。Memcached
的客戶端軟體實現非常多,包括C/C++, PHP, Java, Python, Ruby, Perl, Erlang,
Lua等。當前Memcached使用廣泛,除了LiveJournal以外還有Wikipedia、Flickr、Twitter、Youtube和
WordPress等。

在Window系統下,Memcached的安裝非常方便,只需從以上給出的地址下載可執行軟體然後運行memcached.exe –d
install即可完成安裝。在Linux等系統下,我們首先需要安裝libevent,然後從獲取源碼,make && make
install即可。默認情況下,Memcached的伺服器啟動程序會安裝到/usr/local/bin目錄下。在啟動Memcached時,我們可
以為其配置不同的啟動參數。

1.1 Memcache配置

Memcached伺服器在啟動時需要對關鍵的參數進行配置,下面我們就看一看Memcached在啟動時需要設定哪些關鍵參數以及這些參數的作用。

1)-p <num> Memcached的TCP監聽埠,預設配置為11211;

2)-U <num> Memcached的UDP監聽埠,預設配置為11211,為0時表示關閉UDP監聽;

3)-s <file> Memcached監聽的UNIX套接字路徑;

4)-a <mask> 訪問UNIX套接字的八進制掩碼,預設配置為0700;

5)-l <addr> 監聽的伺服器IP地址,默認為所有網卡;

6)-d 為Memcached伺服器啟動守護進程;

7)-r 最大core文件大小;

8)-u <username> 運行Memcached的用戶,如果當前為root的話需要使用此參數指定用戶;

9)-m <num> 分配給Memcached使用的內存數量,單位是MB;

10)-M 指示Memcached在內存用光的時候返回錯誤而不是使用LRU演算法移除數據記錄;

11)-c <num> 最大並發連數,預設配置為1024;

12)-v –vv –vvv 設定伺服器端列印的消息的詳細程度,其中-v僅列印錯誤和警告信息,-vv在-v的基礎上還會列印客戶端的命令和相應,-vvv在-vv的基礎上還會列印內存狀態轉換信息;

13)-f <factor> 用於設置chunk大小的遞增因子;

14)-n <bytes> 最小的chunk大小,預設配置為48個位元組;

15)-t <num> Memcached伺服器使用的線程數,預設配置為4個;

16)-L 嘗試使用大內存頁;

17)-R 每個事件的最大請求數,預設配置為20個;

18)-C 禁用CAS,CAS模式會帶來8個位元組的冗餘;

2. Redis簡介

Redis是一個開源的key-value存儲系統。與Memcached類似,Redis將大部分數據存儲在內存中,支持的數據類型包括:字
符串、哈希表、鏈表、集合、有序集合以及基於這些數據類型的相關操作。Redis使用C語言開發,在大多數像Linux、BSD和Solaris等
POSIX系統上無需任何外部依賴就可以使用。Redis支持的客戶端語言也非常豐富,常用的計算機語言如C、C#、C++、Object-C、PHP、
Python、Java、Perl、Lua、Erlang等均有可用的客戶端來訪問Redis伺服器。當前Redis的應用已經非常廣泛,國內像新浪、淘
寶,國外像Flickr、Github等均在使用Redis的緩存服務。

Redis的安裝非常方便,只需從http://redis.io/download獲取源碼,然後make && make

install即可。默認情況下,Redis的伺服器啟動程序和客戶端程序會安裝到/usr/local/bin目錄下。在啟動Redis伺服器時,我們
需要為其指定一個配置文件,預設情況下配置文件在Redis的源碼目錄下,文件名為redis.conf。

熱點內容
不用電費比特幣 發布:2025-09-13 19:45:48 瀏覽:652
礦機是怎麼挖幣子的 發布:2025-09-13 19:45:36 瀏覽:36
螞蟻v9礦機可以挖什麼幣種 發布:2025-09-13 19:45:32 瀏覽:465
怎麼理解區塊鏈的共建共贏 發布:2025-09-13 19:43:07 瀏覽:905
阿里區塊鏈商標 發布:2025-09-13 19:35:41 瀏覽:697
港澳大灣區區塊鏈峰會 發布:2025-09-13 19:15:23 瀏覽:750
2019區塊鏈分峰會 發布:2025-09-13 18:51:50 瀏覽:633
挖以太坊調整gpu使用率 發布:2025-09-13 18:47:58 瀏覽:981
發幣地址怎麼跟合約地址一樣 發布:2025-09-13 18:37:58 瀏覽:107
逃離塔科夫怎麼換比特幣 發布:2025-09-13 18:15:10 瀏覽:326