導航:首頁 > 源碼編譯 > redis源碼量

redis源碼量

發布時間:2023-03-07 03:02:27

『壹』 redis之管道應用場景及源碼分析

我們都知道,redis的通信是建立在tcp基礎上的,也就是說每一次命令(get、set)都需要經過tcp三次握手,而且redis一般都是部署在區域網內,網路開銷非常小,針對頻次較低的操作,網路開銷都是可以忽略的。

在redis通信基礎中 我已經講到了。每一次操作redis的時候我們都需要和服務端建立連接,針對量小的情況下網路延遲都是可以忽略的,但是針對大批量的業務,就會產生雪崩效應。假如一次操作耗時2ms,理論上100萬次操作就會有2ms*100萬ms延遲,中間加上伺服器處理開銷,耗時可能更多.對應客戶端來講,這種長時間的耗時是不能接受的。所以為了解決這個問題,redis的管道pipeline就派上用場了。 恰好公司的對賬業務使用了redis的sdiff功能,數據量比較大,剛開始沒有pipeline導致延遲非常嚴重。後來wireshark抓包分析原因確實發現不停的建立tcp連接(發送數據,接收數據)。使用pipeline後性能大幅度提升。

可想而知,使用pipeline的性能要比不使用管道快很多倍。

本文就先到這里了。。。

『貳』 RedisTokenStore 源碼解析 以及內存泄漏問題

前端時間,正好在做公司許可權相關的架構問題,然後選擇了Spring OAuth2來作為公司許可權框架,先記錄下目前遇到原生問題吧,後續有時間再來整理這個框架的整體脈絡;

RedisTokenStore 主要是來做token持久化到redis的工具類

我們先來看下緩存到redis中有哪些key

ACCESS :用來存放 AccessToken 對象(登錄的token值,還有登錄過期時間,token刷新值)
AUTH_TO_ACCESS :緩存的也是AccessToken 對象,是可以根據用戶名和client_id來查找當前用戶的AccessToken
AUTH :用來存放用戶信息(OAuth2Authentication),有許可權信息,用戶信息等
ACCESS_TO_REFRESH :可以根據該值,通過AccessToken找到refreshToken
REFRESH :用來存放refreshToken
REFRESH_TO_ACCESS :根據refreshToken來找到AccessToken
CLIENT_ID_TO_ACCESS :存放當前client_id有多少AccessToken
UNAME_TO_ACCESS :當沒有做單點登錄的話,可以使用該key,根據用戶名查找當前用戶有多少AccessToken可以使用

根據client_id和用戶名,來獲取當前用戶的accessToken,如果緩存中的OAuth2Authentication已經過期,或者雷勇有變化,則會重新更新緩存;

緩存OAuth2AccessToken 和 OAuth2Authentication 對象,該方法主要在登錄時調用,會把上面說的所有key值都緩存起來;

再看下,移除accessToken時

目前主要是看這幾個方法,其他方法也挺簡單的,主要是一些redis緩存操作的;

client_id_to_access 和 uname_to_access 使用的是set集合,眾所周知redis的set集合的過期時間是按照整個key來設置的;
每次登陸時,會先根據client_id和用戶名去緩存中查找是否有可使用的AccessToken,如果有則返回緩存中的值,沒有則生成新的;
所以每次登陸都會往這兩個集合中放入新的accessToken,如果當某個用戶在AccessToken有效期內沒有操作,則當前用戶的登陸信息會被動下線,access 和 auth 中緩存的值都會過期,再次登陸時就查找不到了;
但是如果當前平台用戶量不小,那麼一直都會有人操作,client_id_to_access 這個集合就會一直續期,那麼過期了的accessToken就會一直存在該集合中,且不會減少,造成內存泄漏;

1.自己實現TokenStore,修改client_id_to_access 數據結構
2.寫個定時任務,定期掃描client_id_to_access ,清除掉已經過期的token
3.如果不需要知道當前有哪些用戶登錄,或者該功能已經用了其他方式實現的,可以直接去掉這兩個redis key

『叄』 Redis源碼分析之事件循環

本篇我們來講Redis的事件循環,Redis的事件循環會根據系統選擇evport、epoll、kqueue或select來進行IO多路復用,我們這里只分析epoll。

首先我們來看一下Redis的IO多路復用對事件循環(aeEventLoop)提供的介面。

以epoll(ae_epoll.c)為例,先來看一下Redis的IO多路復用的使用過程:

首先需要創建,即調用aeApiCreate:

aeApiState結構體有兩個成員,events和epfd。events用於存儲就緒的epoll事件,epfd存儲epoll的文件描述符。aeApiCreate的主要邏輯是為aeApiState分配存儲空間,調用epoll_create系統調用創建epoll並獲取描述符,最後將aeApiState賦值給aeEventLoop的apidata。

然後在有新的文件描述符(比如接受了一個新連接)需要加入到epoll中時,調用aeApiAddEvent:

參數fd是需要監視的文件描述符,mask標明是需要監視可讀還是可寫事件。aeApiAddEvent的主要邏輯是調用系統調用epoll_ctl注冊或修改添加事件的監聽類型到epoll。

然後在有文件描述符失效或者需要修改監聽類型時,調用aeApiDelEvent:

參數fd是需要刪除的文件描述符,mask標明是需要刪除可讀還是可寫事件。aeApiDelEvent主要邏輯是調用系統調用epoll_ctl刪除或修改刪除事件的監聽類型到epoll。

然後需要檢查是否有就緒的事件,調用aeApiPoll:

tvp是等待時間,一般而言,這個值是0(不是NULL)代表沒有就緒事件立即返回。主要邏輯是調用系統調用epoll_wait拿到就緒事件保存到events中,然後將events中的就緒事件復制到事件循環aeEventLoop的fired中,最後返回就緒事件的數量。

我們來分析一下Redis的事件循環(ae.c)。

先看主要介面:

創建過程:

初始化aeEventLoop和aeApiState並返回aeEventLoop。

注冊文件事件:

存儲到events中並調用aeApiAddEvent注冊到epoll中。

注冊定時事件:

創建aeTimeEvent並將其插入到定時事件鏈表的頭部。

主循環:

不停的調用aeProcessEvents拉取並處理事件。

接下來看aeProcessEvents的邏輯:

再看一下定時事件的觸發,也就是processTimeEvents的邏輯:

遍歷注冊的定時事件,找出到期的事件並調用處理函數,如果處理函數返回了下次執行的時間,則更新下次觸發的時間,否則刪除該事件。

『肆』 Redis實現優先順序消息隊列及源碼

上午寫了一篇RabbitMQ做優先順序隊列的文章,但是RabbitMQ這種專業的消息隊列,面對不大的業務是有些殺雞焉用牛刀的感覺,而且使用RabbitMQ需要的成本相對較高。
所以我中午抽空寫了這個Redis實現優先順序消息隊列的例子。
相比RabbitMQ,更加簡潔,更易於理解。
源碼地址: https://github.com/SkylerSkr/RedisPriorityMQ
謝謝大家支持!希望多提意見!

『伍』 windows怎麼調試redis源碼

Redis對於linux是官方支持的,安裝和使用沒有什麼好說的,普通使用按照官方指導,5分鍾以內就能搞定。詳情請參考:
http://redis.io/download

但有時候又想在windows下折騰下Redis,可以從redis下載頁面看到如下提示(在頁面中搜索 "windows"):

[plain] view plain
Win64 Unofficial The Redis project does not directly support Windows,
however the Microsoft Open Tech group develops and maintains
an Windows port targeting Win64.

大意就是 Redis官方是不支持windows的,只是 Microsoft Open Tech group 在 GitHub上開發了一個Win64的版本,項目地址是:
https://github.com/MSOpenTech/redis
打開以後,可以直接使用瀏覽器下載,或者Git克隆。
可以在項目主頁右邊找到 zip包下載地址: https://github.com/MSOpenTech/redis/archive/2.8.zip
(注意: dist文件改變了下載地址: https://github.com/MSOpenTech/redis/releases )

『陸』 redis源碼解讀:單線程的redis是如何實現高速緩存的

redis可能是最近幾年最火的緩存資料庫方案了,在各個高並發領域都有應用。

這篇文章,我們將從源代碼的角度來分析一下,為何如此一個高性能,高應用的緩存,會是單線程的方案,當然一個方案的高性能,高並發是多方面的綜合因素,其它的因素我們將在後續解讀。後續分析主要以LINUX操作系統為基礎,這也是redis應用最廣的平台。

單線程最大的受限是什麼?就是CPU,現在伺服器一般已經是多CPU,而單線程只能使用到其中的一個核。

redis作為一個網路內存緩存資料庫,在實現高性能時,主要有4個點。

1.網路高並發,高流量的數據處理。

一個非同步,高效,且對CPU要求不高的網路模型,這個模型主要是由OS來提供的,目前在LINUX最主流使用的是EPOLL,這個網上介紹很多,主要是基於事件驅動的一個非同步模型。

2.程序內部的合理構架,調用邏輯,內存管理。

redis在採用純C實現時,整體調用邏輯很短,但在內存方面,適當的合並了一些對象和對齊,比如sds等,在底層使用了內存池,在不同情況下使用的不太一樣。

但整體處理上沒有NGINX的內池設計巧妙,當然二者不太一樣,NGINX是基於請求釋放的邏輯來設計的,因此針對請求,可以一次申請大塊,分量使用,再最後統一釋放。

3.數據復制的代價,不管是讀取數據或是寫入數據,一般都是需要有數據復制的過程。

數據復制其實就是一次內存,真正的代價是在於存在大VALUE,當value值長度超過16KB時,性能會開始下降。因為單線程的原因,如果存在一個超大VALUE,比如20MB,則會因為這個請求卡住整個線程,導致後續的請求進不來,雖然後面的請求是能快速處理的小請求。

4.redis中數據結構中演算法的代價,有些結構在大數據量時,代價是很高的。

很多時間,大家忽略了演算法的運算代碼,因為像memcached等這類是完全的KV緩存,不存在什麼演算法,除了一個KEY的查找定位HASH演算法。

而redis不一樣,提供了不少高階的數據對象,這些對象具有上層的一些演算法能力,而這些能力是需要比如GEO模塊。

『柒』 MySQL與Redis資料庫連接池介紹(圖示+源碼+代碼演示)

資料庫連接池(Connection pooling)是程序啟動時建立足夠的資料庫連接,並將這些連接組成一個連接池,由程序動態地對池中的連接進行申請,使用,釋放。

簡單的說:創建資料庫連接是一個很耗時的操作,也容易對資料庫造成安全隱患。所以,在程序初始化的時候,集中創建多個資料庫連接,並把他們集中管理,供程序使用,可以保證較快的資料庫讀寫速度,還更加安全可靠。

不使用資料庫連接池

如果不使用資料庫連接池,對於每一次SQL操作,都要走一遍下面完整的流程:

1.TCP建立連接的三次握手(客戶端與 MySQL伺服器的連接基於TCP協議)

2.MySQL認證的三次我收

3.真正的SQL執行

4.MySQL的關閉

5.TCP的四次握手關閉

可以看出來,為了執行一條SQL,需要進行大量的初始化與關閉操作

使用資料庫連接池

如果使用資料庫連接池,那麼會 事先申請(初始化)好 相關的資料庫連接,然後在之後的SQL操作中會復用這些資料庫連接,操作結束之後資料庫也不會斷開連接,而是將資料庫對象放回到資料庫連接池中

資源重用:由於資料庫連接得到重用,避免了頻繁的創建、釋放連接引起的性能開銷,在減少系統消耗的基礎上,另一方面也增進了系統運行環境的平穩性(減少內存碎片以及資料庫臨時進程/線程的數量)。

更快的系統響應速度:資料庫連接池在初始化過程中,往往已經創建了若干資料庫連接置於池中備用。 此時連接的初始化工作均已完成。對於業務請求處理而言,直接利用現有可用連接,避免了從資料庫連接初始化和釋放過程的開銷,從而縮減了系統整體響應時間。

統一的連接管理,避免資料庫連接泄露:在較為完備的資料庫連接池實現中,可根據預先的連接佔用超時設定,強制收回被佔用連接。從而避免了常規資料庫連接操作中可能出現的資源泄露。

如果說你的伺服器CPU是4核i7的,連接池大小應該為((4*2)+1)=9

相關視頻推薦

90分鍾搞懂資料庫連接池技術|linux後台開發

《tcp/ip詳解卷一》: 150行代碼拉開協議棧實現的篇章

學習地址:C/C++Linux伺服器開發/後台架構師【零聲教育】-學習視頻教程-騰訊課堂

需要C/C++ Linux伺服器架構師學習資料加qun 812855908 獲取(資料包括 C/C++,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,ffmpeg 等),免費分享

源碼下載

下載方式:https://github.com/dongyusheng/csdn-code/tree/master/db_pool(Github中下載)

db_pool目錄下有兩個目錄,mysql_pool目錄為MySQL連接池代碼,redis_pool為redis連接池代碼

下面介紹mysql_pool

CDBConn解析

概念: 代表一個數據連接對象實例

相關成員:

m_pDBPool:該資料庫連接對象所屬的資料庫連接池

構造函數: 綁定自己所屬於哪個資料庫連接池

Init()函數: 創建資料庫連接句柄

CDBPool解析

概念:代表一個資料庫連接池

相關成員:

Init()函數:常見指定數量的資料庫實例句柄,然後添加到m_free_list中,供後面使用

GetDBConn()函數: 用於從空閑隊列中返回可以使用的資料庫連接句柄

RelDBConn()函數: 程序使用完該資料庫句柄之後,將句柄放回到空閑隊列中

測試之前,將代碼中的資料庫地址、埠、賬號密碼等改為自己的(代碼中有好幾處)

進入MySQL, 創建mysql_pool_test資料庫

進入到mysql_pool目錄下, 創建一個build目錄並進入

然後輸入如下的命令進行編譯

之後就會在目錄下生成如下的可執行文件

輸入如下兩條命令進行測試: 可以看到不使用資料庫連接池,整個操作耗時4秒左右;使用連接池之後,整個操作耗時2秒左右,提升了一倍

源碼下載

下面介紹redis_pool

測試

進入到redis_pool目錄下, 創建一個build目錄並進入

然後輸入如下的命令進行編譯

之後就會在目錄下生成如下的可執行文件

輸入如下的命令進行測試: 可以看到不使用資料庫連接池,整個操作耗時182ms;使用連接池之後,整個操作耗時21ms,提升了很多

進入redis,可以看到我們新建的key:

『捌』 Redis5設計與源碼分析.pdf

搜搜公眾號"小易哥學呀學",回復"redis.pdf"

閱讀全文

與redis源碼量相關的資料

熱點內容
android滅屏流程 瀏覽:489
如何更改站點文件夾名字 瀏覽:894
如何看伺服器幾核 瀏覽:274
找酒吧設計公司用什麼app 瀏覽:680
基本初等函數的導數公式及導數的運演算法則 瀏覽:915
為什麼小米app啟動廣告關不了 瀏覽:877
空調壓縮機一直不停 瀏覽:511
養殖系統開發源碼 瀏覽:82
pdf的目錄 瀏覽:406
光遇安卓如何一個人拍視頻 瀏覽:277
怨女pdf 瀏覽:708
扭曲伺服器什麼時候開 瀏覽:23
加密貨幣換平台 瀏覽:610
手機內存壓縮軟體 瀏覽:33
生成樹是否與遍歷演算法有關 瀏覽:728
python強化學習迷宮 瀏覽:450
老包子解壓視頻 瀏覽:885
伺服器注冊是什麼意思 瀏覽:419
程序員群體焦慮如何破局 瀏覽:585
程序員在廣州上班 瀏覽:803