国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

redis學(xué)習(xí)筆記 - 進(jìn)階部分

這篇具有很好參考價(jià)值的文章主要介紹了redis學(xué)習(xí)筆記 - 進(jìn)階部分。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

redis單線程如何處理并發(fā)的客戶端,以及為何單線程快?

redis的發(fā)展歷程:

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

redis單線程和多線程的體現(xiàn):

單線程:主要是指Redis的網(wǎng)絡(luò)IO和鍵值對讀寫是由一個(gè)線程來完成的,Redis在處理客戶端的請求時(shí)包括獲取 (socket 讀)、解析、執(zhí)行、內(nèi)容返回 (socket 寫) 等都由一個(gè)順序串行的主線程處理,這就是所謂的“單線程”。這也是Redis對外提供鍵值存儲(chǔ)服務(wù)的主要流程。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

多線程:主要是指Redis的其他功能,如持久化RDB/AOF、異步刪除、集群數(shù)據(jù)同步等,這些均由額外的線程(獨(dú)立redis命令工作線程)執(zhí)行的。

總結(jié):Redis命令工作線程是單線程的,但對整個(gè)Redis來說,是多線程的。

注意:多線程主要是為了提高CPU的利用率,但redis是基于內(nèi)存操作的,它的性能瓶頸可能是內(nèi)存和網(wǎng)絡(luò)帶寬而非CPU,且多線程會(huì)帶來的數(shù)據(jù)同步問題和切換的開銷,故采用單線程足矣。

redis3.x單線程時(shí)代但性能很快的主要原因:

  1. 基于內(nèi)存的操作:redis所有數(shù)據(jù)都存在內(nèi)存中,且所有運(yùn)算都是內(nèi)存級別的。
  2. 數(shù)據(jù)結(jié)構(gòu)簡單:這些簡單的數(shù)據(jù)結(jié)構(gòu)查找和操作的時(shí)間大部分復(fù)雜度都是O(1)。
  3. 多路復(fù)用和非阻塞IO:IO多路復(fù)用監(jiān)聽socket客戶端連接,即可實(shí)現(xiàn)一個(gè)線程處理多個(gè)請求,避免了IO阻塞操作。
  4. 避免了上下文切換:單線程模型,避免了不必要的上下文切換和多線程競爭,且不會(huì)導(dǎo)致死鎖問題。

redis4.x開始引入多線程:

主要目的:解決redis3.x單線程原子命令操作,帶來的經(jīng)典的問題:大key刪除造成主線程(工作線程)卡頓的問題。

于是在 Redis 4.0 中就新增了多線程的模塊,主要是為了解決刪除數(shù)據(jù)效率比較低的問題的。

異步操作:
unlink key
flushdb async
flushall async
把刪除工作交給了后臺(tái)的子線程,達(dá)到“異步惰性刪除”數(shù)據(jù)的目的

惰性刪除lazy free:本質(zhì)是將某些cost(時(shí)間復(fù)雜度,即占用主線程cpu時(shí)間片)較高刪除操作,從redis主線程剝離讓子線程來處理,極大地減少主線阻塞時(shí)間,從而減少刪除導(dǎo)致性能和穩(wěn)定性問題。

redis6/redis7引入多線程IO:

前面提到了,redis是基于內(nèi)存操作的,它主要的性能瓶頸可能是內(nèi)存和網(wǎng)絡(luò)帶寬而非CPU。

Redis的之前的單線程架構(gòu),雖然有些命令操作可以用后臺(tái)線程或子進(jìn)程執(zhí)行(比如數(shù)據(jù)刪除、快照生成、AOF重寫)。隨著網(wǎng)絡(luò)硬件的性能提升,單個(gè)主線程處理網(wǎng)絡(luò)請求(讀寫命令)的速度跟不上底層網(wǎng)絡(luò)硬件的速度,故Redis的性能瓶頸就會(huì)轉(zhuǎn)嫁在網(wǎng)絡(luò)IO的處理上。

Redis6/7采用多個(gè)IO線程來處理網(wǎng)絡(luò)請求,提高網(wǎng)絡(luò)請求的并發(fā)處理,對于讀寫操作命令仍然使用單個(gè)工作線程來處理。

  • Redis處理請求時(shí),網(wǎng)絡(luò)處理經(jīng)常是瓶頸,通過多個(gè)IO線程并行處理網(wǎng)絡(luò)操作,可以提升實(shí)例的整體處理性能。
  • 使用單線程執(zhí)行命令操作,就不用為了保證Lua腳本、事務(wù)的原子性,額外開發(fā)多線程互斥加鎖機(jī)制了。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

從Redis6開始,多 I/O 線程的提升讀寫性能,的主要實(shí)現(xiàn)思路:將主線程的 IO 讀寫任務(wù)拆分給一組獨(dú)立的線程去執(zhí)行,這樣就可以使多個(gè) socket 的讀寫可以并行化了,采用多路 I/O 復(fù)用技術(shù)可以讓單個(gè)線程高效的處理多個(gè)連接請求(盡量減少網(wǎng)絡(luò)IO的時(shí)間消耗),將最耗時(shí)的“Socket的讀取、請求解析、寫入”單獨(dú)外包出去,剩下的命令執(zhí)行仍然由主線程串行執(zhí)行,并和內(nèi)存的數(shù)據(jù)交互。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

總結(jié):redis快的原因是:數(shù)據(jù)結(jié)構(gòu)簡單+內(nèi)存+“IO多路復(fù)用(epoll)+多線程網(wǎng)絡(luò)IO”+“工作線程為單線程”(避免了線程切換和保證線程同步、死鎖等問題的產(chǎn)生)。

  • IO多路復(fù)用可保證單個(gè)線程監(jiān)聽多個(gè)文件描述符fd(即多個(gè)客戶端的連接)(避免了每個(gè)客戶端連接創(chuàng)建一個(gè)線程造成的資源浪費(fèi)和性能下降),進(jìn)而提高單線程的網(wǎng)絡(luò)IO的吞吐能力。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

  • 實(shí)際應(yīng)用中,當(dāng)發(fā)現(xiàn)CPU開銷不大但吞吐量卻沒有提升,則可考慮開啟redis7中的多線程網(wǎng)絡(luò)IO機(jī)制,來提升網(wǎng)絡(luò)IO的吞吐量。

數(shù)據(jù)庫和緩存的一致性:

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

一致性的解決方案:給緩存設(shè)置過期時(shí)間,定期清理緩存并回寫。

如果數(shù)據(jù)庫寫成功,即使緩存更新失敗但只要到達(dá)過期時(shí)間,則后面的讀請求自然會(huì)從數(shù)據(jù)庫中讀取新值然后回填緩存,從而實(shí)現(xiàn)一致性的目的。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

“雙檢加鎖”策略,避免緩存擊穿的問題:

當(dāng)redis中查找數(shù)據(jù)沒有時(shí),加鎖(防止高并發(fā)的請求同時(shí)查找該鍵值,導(dǎo)致緩存擊穿問題)之后(加鎖后,只有一個(gè)線程去查mysql其余的線程在阻塞等待,等該線程回寫數(shù)據(jù)到redis中,則直接查詢r(jià)edis即可)二次查詢還是沒有則查詢mysql并回寫到redis中。

4種更新策略:

  1. 先更新數(shù)據(jù)庫,再更新緩存:

    異常情況一:更新myql成功后,再回寫更新redis失敗,則會(huì)導(dǎo)致在該數(shù)據(jù)過期之前,訪問到的是“臟數(shù)據(jù)”。

    異常情況二:并發(fā)對同一個(gè)數(shù)據(jù)改寫,且先更新mysql再更新redis,由于執(zhí)行過程搶占CPU資源,可能會(huì)導(dǎo)致出現(xiàn)redis和mysql的數(shù)據(jù)不一致的問題。

  2. 先更新緩存,再更新數(shù)據(jù)庫:

    異常情況:并發(fā)對同一個(gè)數(shù)據(jù)改寫,且先更新緩存,再更新數(shù)據(jù)庫,由于執(zhí)行過程搶占CPU資源,可能會(huì)導(dǎo)致出現(xiàn)redis和mysql的數(shù)據(jù)不一致的問題。

  3. 先刪除緩存,再更新數(shù)據(jù)庫:

    異常情況:

    • A線程delete掉redis中的數(shù)據(jù),之后給mysql更新數(shù)據(jù),結(jié)果網(wǎng)絡(luò)阻塞,一直沒更新成功。

    • B線程來讀取,先去讀redis里數(shù)據(jù)(已經(jīng)被A線程刪除了,故沒有命中),此時(shí),B會(huì)從mysql獲取舊值并回寫到redis中,導(dǎo)致的問題:剛被A線程刪除的舊數(shù)據(jù)有極大可能又被寫回了。

      最終,導(dǎo)致mysql和redis中的數(shù)據(jù)不一致,即redis中的是舊數(shù)據(jù)。

    延遲雙刪”的策略:線程A sleep一段時(shí)間時(shí)間后,再次刪除redis中的該數(shù)據(jù)(刪除操作可以異步完成)。

    • 這段sleep的時(shí)間 > 線程B讀取數(shù)據(jù)再寫入緩存的時(shí)間。
    • 目的:確保讀請求結(jié)束后,寫請求可以刪除讀請求造成的緩存臟數(shù)據(jù)。
    • sleep的時(shí)間如何確定?
      1. 自定估算讀mysql數(shù)據(jù)和寫redis緩存的時(shí)間。
      2. 啟動(dòng)后臺(tái)監(jiān)控程序,如WatchDog監(jiān)控工程。

    無法解決的遺留問題:

    1. 先刪除緩存值再更新數(shù)據(jù)庫,有可能導(dǎo)致高并發(fā)的請求因緩存缺失而訪問數(shù)據(jù)庫,導(dǎo)致打滿mysql。
    2. 如果業(yè)務(wù)應(yīng)用中,讀取數(shù)據(jù)庫和寫緩存的時(shí)間不好估算,那延遲雙刪中的sleep時(shí)間就不好設(shè)置。
  4. 先更新數(shù)據(jù)庫,再刪除緩存(推薦使用):

    • 如果業(yè)務(wù)層要求必須讀取一致性的數(shù)據(jù),那就需要在更新數(shù)據(jù)庫時(shí),先在Redis緩存客戶端暫停并發(fā)讀請求,等數(shù)據(jù)庫更新完、緩存值刪除后,再讀取數(shù)據(jù),從而保證數(shù)據(jù)一致性,但實(shí)際的生產(chǎn)環(huán)境中不推薦(嚴(yán)重影響并發(fā)性能)。

      實(shí)際的生產(chǎn)環(huán)境中,分布式下很難滿足“實(shí)時(shí)一致性”,一般都考慮的是最終的一致性。

    • 最終的一致性實(shí)現(xiàn)方案:

    redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

    1. 把要?jiǎng)h除的緩存值/要更新的數(shù)據(jù)庫值暫存到消息隊(duì)列(如Kafka/RabbitMQ等)中。
    2. 當(dāng)程序沒能成功刪除緩存值/更新數(shù)據(jù)庫值時(shí),可以從消息隊(duì)列中重新讀取這些值,然后再次進(jìn)行刪除或更新。
    3. 如果能夠成功地刪除或更新(保證了數(shù)據(jù)庫和緩存的數(shù)據(jù)一致性),就將這些值從消息隊(duì)列中去除,否則還需要再次進(jìn)行重試。
    4. 如果重試超過的一定次數(shù)后還未成功,就需要向業(yè)務(wù)層發(fā)送報(bào)錯(cuò)信息,通知運(yùn)維人員處理。

總結(jié):

策略 高并發(fā)多線程條件下 問題 現(xiàn)象 解決方案
先刪除redis緩存,再更新mysql 緩存刪除成功但數(shù)據(jù)庫更新失敗 程序從數(shù)據(jù)庫中讀到舊值 再次更新數(shù)據(jù)庫,重試
緩存刪除成功但數(shù)據(jù)庫更新中…有并發(fā)讀請求 并發(fā)請求從數(shù)據(jù)庫讀到舊值并回寫到redis,導(dǎo)致后續(xù)(該鍵值過期前)都是從redis讀取到舊值 延遲雙刪
先更新mysql,再刪除redis緩存(推薦,該方式可實(shí)現(xiàn)最終一致性 數(shù)據(jù)庫更新成功,但緩存刪除失敗 該鍵值過期前,程序從redis中讀到舊值 再次刪除緩存,重試
數(shù)據(jù)庫更新成功但緩存刪除中…有并發(fā)讀請求 并發(fā)請求從緩存讀到舊值 等待redis刪除完成,這段時(shí)間有數(shù)據(jù)不一致,短暫存在。

成熟的工程方案–>監(jiān)聽mysql的變動(dòng),并通知redis:

要保證數(shù)據(jù)庫和redis強(qiáng)一致性是不可能的,肯定有少許時(shí)間的不一致。canal是阿里的一套組件,用來監(jiān)聽mysql master發(fā)送的類似binary log的數(shù)據(jù),然后讓消息者去消費(fèi)。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

傳統(tǒng)的MySQL的主從復(fù)制:

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

MySQL的主從復(fù)制將經(jīng)過如下步驟:

  1. 當(dāng) master 主服務(wù)器上的數(shù)據(jù)發(fā)生改變時(shí),則將其改變寫入二進(jìn)制事件日志文件 bin log 中;

  2. salve 從服務(wù)器會(huì)在一定時(shí)間間隔內(nèi)對 master 主服務(wù)器上的二進(jìn)制日志進(jìn)行探測,探測其是否發(fā)生過改變。

    如果探測到 master 主服務(wù)器的二進(jìn)制事件日志發(fā)生了改變,則開始一個(gè) I/O Thread 請求 master 二進(jìn)制事件日志;

  3. 同時(shí) master 主服務(wù)器為每個(gè) I/O Thread 啟動(dòng)一個(gè)dump Thread,用于向其發(fā)送二進(jìn)制事件日志;

  4. slave 從服務(wù)器將接收到的二進(jìn)制事件日志保存至自己本地的中繼日志文件 relay log 中;

  5. salve 從服務(wù)器將啟動(dòng) SQL Thread 從中繼日志中讀取二進(jìn)制日志,在本地重放,使得其數(shù)據(jù)和主服務(wù)器保持一致;

  6. 最后 I/O Thread 和 SQL Thread 將進(jìn)入睡眠狀態(tài),等待下一次被喚醒;

canal的工作原理:

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

  1. canal 模擬 MySQL slave 的交互協(xié)議,偽裝自己是 MySQL slave,向 MySQL master 發(fā)送 dump 協(xié)議;
  2. MySQL master 收到 dump 請求,開始推送 bin log 給 slave,即 canel;
  3. canel 解析 bin log 對象(原始為 bytes 流)。

詳細(xì)介紹:Canal 采集MySQL binlog日志。

canel的作用:

  1. 數(shù)據(jù)庫鏡像;
  2. 數(shù)據(jù)庫實(shí)時(shí)備份;
  3. 索引構(gòu)建和實(shí)時(shí)維護(hù)(拆分異構(gòu)索引、倒排索引等);
  4. 業(yè)務(wù)cache的刷新;
  5. 帶業(yè)務(wù)邏輯的增量數(shù)據(jù)處理;

布隆過濾器:

應(yīng)用場景:

  1. 解決緩存穿透的問題:當(dāng)查詢一個(gè)數(shù)據(jù)庫也不存在的數(shù)據(jù)時(shí),會(huì)造成每次先redis查不到之后都去訪問數(shù)據(jù)庫。

    造成的后果:當(dāng)有大量請求查詢數(shù)據(jù)庫不存在的數(shù)據(jù)時(shí),就會(huì)給數(shù)據(jù)庫帶來壓力,甚至?xí)峡鍞?shù)據(jù)庫。

    使用布隆過濾器解決緩存穿透的問題:把已存在數(shù)據(jù)的key存在布隆過濾器中。

    • 如果布隆過濾器中不存在該條數(shù)據(jù),則數(shù)據(jù)庫中一定不存在該數(shù)據(jù),可直接返回;(避免了緩存擊穿問題)

    • 如果布隆過濾器中已存在(可能數(shù)據(jù)庫也不存在該數(shù)據(jù)),先去查詢緩存redis,沒有再去查詢Mysql數(shù)據(jù)庫。

    redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

    redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

  2. 黑名單校驗(yàn),識別垃圾郵件

    解決方案:把所有億萬個(gè)黑名單都放在布隆過濾器中,在收到郵件時(shí),判斷郵件地址是否在布隆過濾器中即可(布隆過濾器中沒有該郵件地址,則該地址一定不在黑名單中,即一定不是垃圾郵件)。

  3. 白名單校驗(yàn),識別出合法用戶;

    redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

  4. 準(zhǔn)確快速的判斷50億個(gè)電話號碼中,是否存在這10萬個(gè)?

原理:

  1. 底層結(jié)構(gòu):由初值為0的bit數(shù)組和一系列無偏hash函數(shù)(無偏主要是為了分布均勻,盡可能的避免hash沖突)構(gòu)成,用來快速判斷集合中是否存在某個(gè)元素。存在一定的誤判概率。

    redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

  2. 目的:在不保存數(shù)據(jù)信息的前提下,只是在內(nèi)存中做一個(gè)是否存在的標(biāo)記flag。

    實(shí)現(xiàn)高效的插入和查詢(不能刪除元素,會(huì)導(dǎo)致誤判率增加(布隆過濾器的每一個(gè) bit 并不是獨(dú)占的,很有可能多個(gè)元素共享了某一位。如果我們直接刪除這一位的話,會(huì)影響其他的元素)),且用極少的內(nèi)存空間,但返回的結(jié)果是不確定的并不完美(判斷不存在時(shí),則一定不存在;判斷為存在時(shí),可能不存在)。

    總結(jié):布隆過濾器判斷一個(gè)元素不在一個(gè)集合中,則該元素一定不在該集合中。判斷為存在時(shí),可能不存在。

  3. 添加key:用所有hash函數(shù)進(jìn)行計(jì)算int index = hash(key) % bloom_filter_len,并將這些索引對應(yīng)的位置均置1。

    redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

    查詢key只要有其中一位是0,就表示這個(gè)key不存在,但如果都是1則不一定存在對應(yīng)的key。

    redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

  4. 誤判:指多個(gè)輸入經(jīng)過哈希后相同的 bit 位被置1了,這樣就無法判斷究竟是哪個(gè)輸入產(chǎn)生的,即誤判的根源在于相同的 bit 位被多次映射且置1。

  5. 當(dāng)實(shí)際元素?cái)?shù)量超過初始化數(shù)量時(shí),應(yīng)該對布隆過濾器進(jìn)行重建,即重新分配一個(gè)size更大的過濾器并將所有歷史元素批量添加進(jìn)去。

緩存創(chuàng)建的問題:

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

redis緩存淘汰機(jī)制:

redis內(nèi)存管理:

  • redis配置文件:maxmemory參數(shù)設(shè)置了redis占用的最大內(nèi)存,單位是bytes字節(jié)。

    默認(rèn)情況下,64位操作系統(tǒng)不限制內(nèi)存大小,32位系統(tǒng)最多使用3G(推薦占用物理內(nèi)存的3/4)。

  • 通過config get maxmemory 104857600config get maxmemory命令,來設(shè)置和獲取redis的最大內(nèi)存占用。

    info memory,可查看redis的內(nèi)存使用情況。

注意:如果redis中的數(shù)據(jù)未設(shè)置過期時(shí)間,且已到達(dá)maxmemory的內(nèi)存上限,這時(shí)再添加數(shù)據(jù)會(huì)OOM。為避免這種問題,引入了內(nèi)存淘汰機(jī)制。

三種不同的過期鍵刪除策略:

  1. 立即刪除:redis不可能時(shí)時(shí)刻刻遍歷所有被設(shè)置了過期時(shí)間的key,而且一直選擇立即刪除的話,會(huì)產(chǎn)生大量的CPU性能消耗,同時(shí)也會(huì)影響數(shù)據(jù)的讀取操作。

    總結(jié):用處理器性能換取內(nèi)存空間,即用時(shí)間換空間

  2. 惰性刪除(lazyfree-lazy-eviction=yes開啟):數(shù)據(jù)到達(dá)過期時(shí)間不做處理,等下次訪問時(shí),發(fā)現(xiàn)已過期則刪除。

    存在的問題:如果已過期的數(shù)據(jù),一段時(shí)間內(nèi)均未訪問到,則會(huì)白白占用內(nèi)存空間。

    總結(jié):對memory不友好,用內(nèi)存空間換取處理器性能,即用空間換時(shí)間。

  3. 定期(抽檢key)刪除(前兩種策略的折中):每隔一段時(shí)間執(zhí)行一次刪除過期鍵操作,并通過限制刪除操作執(zhí)行時(shí)長和頻率,來減少刪除操作對CPU時(shí)間的影響(服務(wù)器要根據(jù)實(shí)際情況,合理設(shè)置刪除操作的執(zhí)行時(shí)長、頻率)。

    周期性輪詢r(jià)edis庫中的時(shí)效性數(shù)據(jù),采用隨機(jī)抽取的策略,利用過期數(shù)據(jù)占比的方式控制刪除頻度:

    1. CPU性能占用設(shè)置有峰值,檢測頻度可自定義設(shè)置;
    2. 內(nèi)存壓力不是很大,長期占用內(nèi)存的冷數(shù)據(jù)會(huì)被持續(xù)清理;

    總結(jié):周期性抽查內(nèi)存空間(隨機(jī)抽查,重點(diǎn)抽查)。

上述“惰性刪除、定期(抽檢)刪除”中,惰性刪除時(shí)從未被點(diǎn)中使用過,定期刪除時(shí)從未被抽查到,均會(huì)造成大量過期key堆積在內(nèi)存中,導(dǎo)致redis內(nèi)存空間緊張。

redis緩存淘汰策略:

redis配置文件:

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

  • noeviction:不會(huì)驅(qū)逐任何key,表示即使內(nèi)存達(dá)到上限也不進(jìn)行置換,之后所有能引起內(nèi)存增加的命令都會(huì)返回error。
  • volatile-lru:對所有設(shè)置了過期時(shí)間的key使用LRU算法,進(jìn)行刪除。
  • allkeys-lru:對所有key使用LRU算法進(jìn)行刪除,優(yōu)先刪除最近最不常使用的key。
  • volatile-lfu:對所有設(shè)置了過期時(shí)間的key使用LFU算法,進(jìn)行刪除。
  • allkeys-lfu:對所有key使用LFU算法,進(jìn)行刪除。
  • volatile-random:對所有設(shè)置了過期時(shí)間的key,進(jìn)行隨機(jī)刪除。
  • allkeys-random:對所有key,進(jìn)行隨機(jī)刪除。
  • volatile-ttl刪除快過期的key。

LRU和LFU的區(qū)別:

  1. LRU:最近最少使用頁面置換算法,淘汰最長時(shí)間未被使用的頁面,看頁面最后一次被使用到發(fā)生調(diào)度的時(shí)間長短,首先淘汰最長時(shí)間未被使用的頁面。
  2. LFU:最近最不常用頁面置換算法,淘汰一定時(shí)期內(nèi)被訪問次數(shù)最少的頁,看一定時(shí)間段內(nèi)頁面被使用的頻率,淘汰一定時(shí)期內(nèi)被訪問次數(shù)最少的頁。

配置性能建議:

  • 避免存儲(chǔ)bigkey。
  • 開啟惰性刪除,lazyfree-lazy-eviction=yes。

redis經(jīng)典的五大類型源碼及底層實(shí)現(xiàn):

底層數(shù)據(jù)結(jié)構(gòu):

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

  1. 字符串:Redis會(huì)根據(jù)當(dāng)前值的類型和長度決定使用哪種內(nèi)部編碼實(shí)現(xiàn)。

    int:8個(gè)字節(jié)的長整型。

    embstr:小于等于44個(gè)字節(jié)的字符串。

    raw:大于44個(gè)字節(jié)的字符串。

  2. 哈希:

    ziplist(壓縮列表):當(dāng)哈希類型元素個(gè)數(shù)小于hash-max-ziplist-entries配置(默認(rèn)512個(gè))、同時(shí)所有值都小于hash-max-ziplist-value配置(默認(rèn)64 字節(jié))時(shí),Redis會(huì)使用ziplist作為哈希的內(nèi)部實(shí)現(xiàn),ziplist使用更加緊湊的結(jié)構(gòu)實(shí)現(xiàn)多個(gè)元素的連續(xù)存儲(chǔ),故比hashtable更加節(jié)省內(nèi)存。

    hashtable(哈希表):當(dāng)哈希類型無法滿足ziplist的條件時(shí),Redis會(huì)使用hashtable作為哈希的內(nèi)部實(shí)現(xiàn),因大量元素會(huì)導(dǎo)致ziplist的讀寫效率下降,而hashtable的讀寫時(shí)間復(fù)雜度為O(1)。

  3. 列表:

    ziplist(壓縮列表):當(dāng)列表的元素個(gè)數(shù)小于list-max-ziplist-entries配置(默認(rèn)512個(gè))、同時(shí)列表中每個(gè)元素的值都小于list-max-ziplist-value時(shí)(默認(rèn)64字節(jié)),Redis會(huì)選用ziplist來作為列表的內(nèi)部實(shí)現(xiàn)來減少內(nèi)存的使用。

    linkedlist(鏈表):當(dāng)列表類型無法滿足ziplist的條件時(shí),Redis會(huì)使用linkedlist作為列表的內(nèi)部實(shí)現(xiàn)。

    注意:redis7之后,quicklist會(huì)將ziplistlinkedlist的結(jié)合,即以ziplist為節(jié)點(diǎn)的雙向鏈表linkedlist。

  4. 集合:

    intset(整數(shù)集合):當(dāng)集合中的元素都是整數(shù)且元素個(gè)數(shù)小于set-max-intset-entries配置(默認(rèn)512個(gè))時(shí),Redis會(huì)用intset來作為集合的內(nèi)部實(shí)現(xiàn),從而減少內(nèi)存的使用。

    hashtable(哈希表):當(dāng)集合類型無法滿足intset的條件時(shí),Redis會(huì)使用hashtable作為集合的內(nèi)部實(shí)現(xiàn)。

  5. 有序集合:

    ziplist(壓縮列表):當(dāng)有序集合的元素個(gè)數(shù)小于zset-max-ziplist- entries配置(默認(rèn)128個(gè)),同時(shí)每個(gè)元素的值都小于zset-max-ziplist-value配置(默認(rèn)64字節(jié))時(shí),Redis會(huì)用ziplist來作為有序集合的內(nèi)部實(shí)現(xiàn),從而有效的減少內(nèi)存使用。

    skiplist(跳躍表):當(dāng)ziplist條件不滿足時(shí),有序集合會(huì)使用skiplist作為內(nèi)部實(shí)現(xiàn),因?yàn)榇藭r(shí)ziplist的讀寫效率會(huì)下降。

注意:redis7會(huì)將ziplist換成了listpack,其通過每個(gè)節(jié)點(diǎn)記錄自己的長度且放在節(jié)點(diǎn)的尾部,徹底解決掉了 ziplist 存在的連鎖更新的問題。

redis字典數(shù)據(jù)庫kv鍵值對是什么?

怎么實(shí)現(xiàn)的鍵值對數(shù)據(jù)庫?

key:一般都是String類型的字符串對象。

value:是redis對象,如字符串對象,集合類型的對象:list對象,set對象,hash對象,zset對象。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

注意:每個(gè)鍵值對,都會(huì)有一個(gè)dictEntry。redis中,每個(gè)對象都是一個(gè)redisObject結(jié)構(gòu)體,redisObject中定義了type和encoding字段對不同的數(shù)據(jù)類型加以區(qū)別,即簡單來說:redisObject就是string、hash、list、set、zset的父類。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

string數(shù)據(jù)結(jié)構(gòu):

SDS簡單動(dòng)態(tài)字符串:

采用len記錄字符串的長度,比起c語言用\0作為字符串的終止判斷更安全。采用預(yù)分配alloc的機(jī)制,大大降低了內(nèi)存碎片的產(chǎn)生。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

注意:embstrraw類型的底層數(shù)據(jù)結(jié)構(gòu),就是SDS(簡單動(dòng)態(tài)字符串)。

底層編碼方式 細(xì)節(jié)說明
int Long類型整數(shù)時(shí),RedisObject中的ptr指針直接賦值為整數(shù)數(shù)據(jù),不再額外的指針再指向整數(shù)了,節(jié)省了指針的空間開銷。
embstr 當(dāng)待保存的字符串小于等于44字節(jié)時(shí),embstr類型將會(huì)調(diào)用內(nèi)存分配函數(shù),只分配一塊連續(xù)的內(nèi)存空間,空間中依次包含 redisObject 與 sdshdr 兩個(gè)數(shù)據(jù)結(jié)構(gòu),讓元數(shù)據(jù)、指針和SDS是一塊連續(xù)內(nèi)存區(qū)域,避免產(chǎn)生內(nèi)存碎片。
raw 當(dāng)待保存的字符串大于44字節(jié)時(shí),SDS的數(shù)據(jù)量變多變大了,會(huì)給SDS分配多的空間并用指針指向SDS結(jié)構(gòu),raw 類型將會(huì)調(diào)用兩次內(nèi)存分配函數(shù),分配兩塊內(nèi)存空間,一塊用于包含 redisObject 結(jié)構(gòu),而另一塊用于包含 sdshdr 結(jié)構(gòu)。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

3大物理編碼方式:

int:

保存long型(長整型)的64位(8字節(jié))有符號整數(shù)。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

注意:int最多是19位,且浮點(diǎn)數(shù)在redis內(nèi)部會(huì)用字符串保存。

embstr:

代表embstr格式的SDS(Simple Dynamic String)簡單動(dòng)態(tài)字符串,保存長度小于44字節(jié)的字符串。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

優(yōu)點(diǎn):使用連續(xù)的內(nèi)存空間存儲(chǔ),避免了內(nèi)存碎片的產(chǎn)生。

raw:

保存長度大于44字節(jié)的字符串。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

三種編碼的轉(zhuǎn)變邏輯:

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

hash數(shù)據(jù)結(jié)構(gòu):

hash的兩種編碼:redis6 --> ziplist + hashtable 、redis7 --> listpack + hashtable 。

redis6:

hash-max-ziplist-entries:使用壓縮列表保存時(shí),哈希集合中的最大元素個(gè)數(shù)

hash-max-ziplist-value:使用壓縮列表保存時(shí),哈希集合中單個(gè)元素的最大長度。

Hash類型鍵的字段個(gè)數(shù) 小于hash-max-ziplist-entries并且每個(gè)字段名和字段值的長度 小于hash-max-ziplist-value時(shí),Redis才會(huì)使用OBJ_ENCODING_ZIPLIST來存儲(chǔ)該鍵,任意一個(gè)不滿足則會(huì)轉(zhuǎn)換為OBJ_ENCODING_HT的編碼方式。

一旦底層編碼從壓縮列表OBJ_ENCODING_ZIPLIST轉(zhuǎn)為了哈希表OBJ_ENCODING_HT,Hash類型就會(huì)一直用哈希表進(jìn)行保存而不會(huì)再轉(zhuǎn)回壓縮列表了,但在節(jié)省內(nèi)存空間方面哈希表就沒有壓縮列表高效了。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

OBJ_ENCODING_HT這種編碼方式內(nèi)部才是真正的哈希表結(jié)構(gòu),稱為字典結(jié)構(gòu),其可以實(shí)現(xiàn)O(1)復(fù)雜度的讀寫操作,因此效率很高。從OBJ_ENCODING_HT類型到底層真正的散列表數(shù)據(jù)結(jié)構(gòu)是一層層嵌套下去的,組織關(guān)系見面圖:

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

側(cè)面證明:每個(gè)鍵值對都有一個(gè)dictEntry節(jié)點(diǎn)。

ziplist壓縮列表,是一種緊湊的連續(xù)存儲(chǔ)的“雙向鏈表”編碼格式(每個(gè)節(jié)點(diǎn)不再存儲(chǔ)prev、next指針,而是存儲(chǔ)上一個(gè)節(jié)點(diǎn)和當(dāng)前節(jié)點(diǎn)的長度),以部分的讀寫性能為代價(jià),換取極高的內(nèi)存空間利用率。 一般適用于字段個(gè)數(shù)少,字段值也比較小的場景。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

最主要的是節(jié)點(diǎn)zlentry中,包含了前一個(gè)節(jié)點(diǎn)的長度prevrawlensize、當(dāng)前節(jié)點(diǎn)的長度lensize、當(dāng)前節(jié)點(diǎn)的類型encoding和當(dāng)前節(jié)點(diǎn)的實(shí)際數(shù)據(jù)p

總結(jié):

  1. ziplist為了節(jié)省內(nèi)存,采用緊湊的連續(xù)存儲(chǔ)格式。
  2. ziplist作為一個(gè)雙向鏈表,可在時(shí)間復(fù)雜度為O(1)下,從頭部、尾部進(jìn)行pop、push,即頭插尾插效率高。
  3. 致命缺點(diǎn):插入/更新元素時(shí),可能會(huì)出現(xiàn)連鎖更新現(xiàn)象,導(dǎo)致其被listpack替換。
  4. 一般適用于字段個(gè)數(shù)少,字段值也比較小的場景。過多的字段,會(huì)導(dǎo)致查詢/插入效率的降低。

redis7:

hash-max-listpack-entries:使用壓縮列表保存時(shí),哈希集合中的最大元素個(gè)數(shù)。

hash-max-listpack-value:使用壓縮列表保存時(shí),哈希集合中單個(gè)元素的最大長度。

Hash類型鍵的字段個(gè)數(shù) 小于hash-max-listpack-entries并且每個(gè)字段名和字段值的長度 小于hash-max-listpack-value時(shí),Redis才會(huì)使用OBJ_ENCODING_LISTPACK來存儲(chǔ)該鍵,任意一個(gè)不滿足則會(huì)轉(zhuǎn)換為OBJ_ENCODING_HT的編碼方式。

有了ziplist,為何還需要listpack緊湊列表?

  1. ziplist壓縮列表的每個(gè)節(jié)點(diǎn)中 prevlen 屬性,記錄前一個(gè)節(jié)點(diǎn)占用的長度,

    redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

    • 如果前一個(gè)節(jié)點(diǎn)的長度 < 254bytes,則 prevlen 屬性需要占用 1bytes 來存儲(chǔ)前一個(gè)節(jié)點(diǎn)的長度值。
    • 如果前一個(gè)節(jié)點(diǎn)的長度 >= 254bytes,則 prevlen 屬性需要占用 5bytes 來存儲(chǔ)前一個(gè)節(jié)點(diǎn)的長度值。
  2. 壓縮列表新增某個(gè)元素或修改某個(gè)元素時(shí),如果空間不夠,壓縮列表占用的內(nèi)存空間就需要重新分配。

    當(dāng)新插入的元素較大時(shí),可能會(huì)導(dǎo)致后續(xù)元素的 prevlen 占用空間都發(fā)生變化,從而引起連鎖更新問題,導(dǎo)致每個(gè)元素的空間都要重新分配,造成訪問壓縮列表性能下降。

    redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

  3. listpack 是 Redis 設(shè)計(jì)用來取代掉 ziplist 的數(shù)據(jù)結(jié)構(gòu),它通過每個(gè)節(jié)點(diǎn)記錄自己的長度且放在節(jié)點(diǎn)的尾部,來徹底解決掉了 ziplist 存在的連鎖更新的問題。

    redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

list數(shù)據(jù)結(jié)構(gòu):

ziplist壓縮列表和linkedlist雙端鏈表的對比:

  • ziplist的優(yōu)點(diǎn):內(nèi)存緊湊,訪問效率高;缺點(diǎn):更新效率低,可能引發(fā)“連鎖更新”的問題。
  • linkedlist的優(yōu)點(diǎn):節(jié)點(diǎn)的修改效率高;缺點(diǎn):需要額外的內(nèi)存開銷,節(jié)點(diǎn)較多時(shí)會(huì)產(chǎn)生大量的內(nèi)存碎片。

總結(jié):quicklist結(jié)合了ziplistlinkedlist的優(yōu)點(diǎn),是“雙向鏈表 + 壓縮列表”組合:鏈表中每個(gè)元素是一個(gè)壓縮列表。

list中quicklist的兩種編碼:redis6 --> linkedlist + ziplist 、redis7 --> linkedlist + listpack 。

redis6:

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

  1. ziplist 壓縮配置list-compress-depth,表示一個(gè) quicklist 兩端不被壓縮的節(jié)點(diǎn)個(gè)數(shù)。這里的節(jié)點(diǎn)是指 quicklist 雙向鏈表的節(jié)點(diǎn),而非 ziplist 里面的數(shù)據(jù)項(xiàng)個(gè)數(shù)。取值含義如下:
  • 0:是 Redis 的默認(rèn)值,表示都不壓縮。
  • 1:quicklist 兩端各有1個(gè)節(jié)點(diǎn)不壓縮,中間的節(jié)點(diǎn)壓縮。
  • 2:quicklist 兩端各有2個(gè)節(jié)點(diǎn)不壓縮,中間的節(jié)點(diǎn)壓縮。
  • 3:quicklist 兩端各有3個(gè)節(jié)點(diǎn)不壓縮,中間的節(jié)點(diǎn)壓縮。
  1. ziplist 中 entry 配置list-max-ziplist-size
  • 當(dāng)取正值時(shí),表示按照數(shù)據(jù)項(xiàng)個(gè)數(shù)來限定每個(gè) quicklist 節(jié)點(diǎn)上的 ziplist 長度。

    比如,當(dāng)這個(gè)參數(shù)配置成5的時(shí)候,表示每個(gè) quicklist 節(jié)點(diǎn)的 ziplist 最多包含5個(gè)數(shù)據(jù)項(xiàng)。

  • 當(dāng)取負(fù)值時(shí),表示按照占用字節(jié)數(shù)來限定每個(gè) quicklist 節(jié)點(diǎn)上的 ziplist 長度。這時(shí),它只能取 -1 到 -5 這五個(gè)值。

    取值含義如下:

    -5:每個(gè) quicklist 節(jié)點(diǎn)上的 ziplist 大小不能超過64 Kb。(注:1kb => 1024 bytes)

    -4:每個(gè) quicklist 節(jié)點(diǎn)上的 ziplist 大小不能超過32 Kb。

    -3:每個(gè) quicklist 節(jié)點(diǎn)上的 ziplist 大小不能超過16 Kb。

    -2(Redis的默認(rèn)值):每個(gè) quicklist 節(jié)點(diǎn)上的 ziplist 大小不能超過8 Kb。

    -1:每個(gè) quicklist 節(jié)點(diǎn)上的 ziplist 大小不能超過4 Kb。

redis7:

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

主要與redis6的區(qū)別(listpack 替換了 ziplist):即通過每個(gè)節(jié)點(diǎn)記錄自己的長度且放在節(jié)點(diǎn)的尾部,來徹底解決掉了 ziplist 存在的連鎖更新的問題。

set數(shù)據(jù)結(jié)構(gòu):

兩種編碼格式:intset、hashtable

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

zset數(shù)據(jù)結(jié)構(gòu):

編碼格式:redis6 --> ziplist + skiplist、redis7 --> listpack + skiplist。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

  • 當(dāng)有序集合中包含的元素?cái)?shù)量超過服務(wù)器屬性 zset_max_ziplist_entries 的值(默認(rèn)值為 128 )時(shí)
  • 有序集合中新添加元素的長度大于服務(wù)器屬性 zset_max_ziplist_value 的值(默認(rèn)值為 64 )時(shí)

,redis會(huì)使用跳躍表 skiplist 作為有序集合的底層實(shí)現(xiàn),否則會(huì)使用 ziplist/listpack。

skiplist跳表:

引出:

對于一個(gè)單鏈表來講,即便鏈表中存儲(chǔ)的數(shù)據(jù)是有序的,如果要想在其中查找某個(gè)數(shù)據(jù),也只能從頭到尾遍歷鏈表,時(shí)間復(fù)雜度很高O(N)。

解決方法:升維,即最典型的空間換時(shí)間解決方案。實(shí)現(xiàn)細(xì)節(jié)問題:

  • 鏈表無法進(jìn)行二分查找,故借鑒數(shù)據(jù)庫索引的思想,提取出鏈表中關(guān)鍵節(jié)點(diǎn)(作為索引),先在關(guān)鍵節(jié)點(diǎn)上查找,再進(jìn)入下層鏈表查找,提取多層關(guān)鍵節(jié)點(diǎn),就形成了跳躍表。
  • 由于索引也要占據(jù)一定空間的,所以,索引添加的越多,空間占用的越多。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

特性:

  1. skiplist就是實(shí)現(xiàn)二分查找的有序鏈表,即“跳表=鏈表+多級索引”。
  2. 跳表的時(shí)間復(fù)雜度O(logN),空間復(fù)雜度O(N)。

redis學(xué)習(xí)筆記 - 進(jìn)階部分,數(shù)據(jù)庫,redis,學(xué)習(xí),筆記

適用場景:

只有在**數(shù)據(jù)量較大且讀多寫少**的情況下,才能體現(xiàn)出來優(yōu)勢。

缺點(diǎn):

維護(hù)成本相對要高,新增/刪除元素時(shí)需要把所有索引都更新一遍,且為了保證原始鏈表中數(shù)據(jù)的有序性需要先找到要?jiǎng)幼鞯奈恢?,之后才能插?刪除并更新索引。文章來源地址http://www.zghlxwxcb.cn/news/detail-678493.html

到了這里,關(guān)于redis學(xué)習(xí)筆記 - 進(jìn)階部分的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 網(wǎng)絡(luò)安全進(jìn)階學(xué)習(xí)第十二課——SQL手工注入3(Access數(shù)據(jù)庫)

    網(wǎng)絡(luò)安全進(jìn)階學(xué)習(xí)第十二課——SQL手工注入3(Access數(shù)據(jù)庫)

    判斷數(shù)據(jù)庫類型 —— 判斷表名 —— 判斷列名 —— 判斷列名長度 —— 查出數(shù)據(jù)。 asp的網(wǎng)站,常用數(shù)據(jù)庫為access、sqlserver。 and exsits (select * from msysobjects)0 access and exsits (select * from sysobjects)0 sqlserver 上述語句 會(huì)返回1或者0 。 msysobjects是access的默認(rèn)數(shù)據(jù)庫 , sysobjects是sqlserv

    2024年02月11日
    瀏覽(29)
  • C++集群聊天服務(wù)器 muduo+nginx+redis+mysql數(shù)據(jù)庫連接池 筆記 (下)

    C++集群聊天服務(wù)器 muduo+nginx+redis+mysql數(shù)據(jù)庫連接池 筆記 (下)

    C++集群聊天服務(wù)器 網(wǎng)絡(luò)模塊+業(yè)務(wù)模塊+CMake構(gòu)建項(xiàng)目 筆記 (上)-CSDN博客 https://blog.csdn.net/weixin_41987016/article/details/135991635?spm=1001.2014.3001.5501 C++集群聊天服務(wù)器 數(shù)據(jù)模塊+業(yè)務(wù)模塊+CMake構(gòu)建項(xiàng)目 筆記 (上)-CSDN博客 https://blog.csdn.net/weixin_41987016/article/details/136007616?spm=1001.2014.

    2024年02月19日
    瀏覽(33)
  • MYSQL數(shù)據(jù)庫學(xué)習(xí)筆記

    以分號結(jié)尾加回車為一個(gè)命令 show databases;//展示所有數(shù)據(jù)庫 create database xxx;//創(chuàng)建新的數(shù)據(jù)庫 create database if not exists xxx;//檢查是否創(chuàng)建XXX數(shù)據(jù)庫,沒有則創(chuàng)建,有則不創(chuàng)建 create database default charset (字節(jié)大小);//創(chuàng)建指定字節(jié)大小的數(shù)據(jù)庫 drop database xxx;//刪除數(shù)據(jù)庫 use xxx;//使用

    2024年02月16日
    瀏覽(29)
  • MySQL數(shù)據(jù)庫學(xué)習(xí)筆記(二)

    排序查詢 :select 字段列表 from [表名]? order by ?[字段名1] [asc升序/desc降序,默認(rèn)值為升序],[字段名2] [排序方式];//字段名1為優(yōu)先級排序,如果字段名1有相同的,再以字段名2排序 聚合函數(shù) : count 統(tǒng)計(jì)數(shù)量(一般不選null的列) max 最大值 min 最小值 sum 總和 avg 平均值 Select

    2024年02月11日
    瀏覽(27)
  • python學(xué)習(xí)筆記(三)—數(shù)據(jù)庫篇

    數(shù)據(jù)庫編程是指在應(yīng)用程序中使用數(shù)據(jù)庫管理系統(tǒng)(DBMS)進(jìn)行數(shù)據(jù)存儲(chǔ)、檢索和處理的過程。數(shù)據(jù)庫提供了一種結(jié)構(gòu)化的方式來組織和存儲(chǔ)數(shù)據(jù),使得數(shù)據(jù)的管理更加高效和可靠。 關(guān)系數(shù)據(jù)庫是一種基于關(guān)系模型的數(shù)據(jù)庫系統(tǒng),使用表(表格)來存儲(chǔ)和組織數(shù)據(jù)。每個(gè)表由

    2024年02月11日
    瀏覽(20)
  • 網(wǎng)絡(luò)安全全棧培訓(xùn)筆記(55-服務(wù)攻防-數(shù)據(jù)庫安全&Redis&Hadoop&Mysqla&未授權(quán)訪問&RCE)

    網(wǎng)絡(luò)安全全棧培訓(xùn)筆記(55-服務(wù)攻防-數(shù)據(jù)庫安全&Redis&Hadoop&Mysqla&未授權(quán)訪問&RCE)

    知識點(diǎn): 1、服務(wù)攻防數(shù)據(jù)庫類型安全 2、RedisHadoopMysql安全 3、Mysql-CVE-2012-2122漏洞 4、Hadoop-配置不當(dāng)未授權(quán)三重奏RCE漏洞 3、Redis-配置不當(dāng)未授權(quán)三重奏RCE兩漏洞 #章節(jié)內(nèi)容: 常見服務(wù)應(yīng)用的安全測試: 1、配置不當(dāng)-未授權(quán)訪問 2、安全機(jī)制特定安全漏洞 3、安全機(jī)制弱口令爆

    2024年01月23日
    瀏覽(30)
  • SQL學(xué)習(xí)筆記——?jiǎng)?chuàng)建數(shù)據(jù)庫和表

    SQL學(xué)習(xí)筆記——?jiǎng)?chuàng)建數(shù)據(jù)庫和表

    一、創(chuàng)建數(shù)據(jù)庫和表 1、創(chuàng)建數(shù)據(jù)庫 打開?SSMS(Microsoft SQL Server Management Studio)→新建查詢→輸入如下圖的sql語句→點(diǎn)擊執(zhí)行 成功后可以看到左側(cè)數(shù)據(jù)庫中成功創(chuàng)建了“CPXS”產(chǎn)品銷售數(shù)據(jù)庫。對應(yīng)路徑下新增數(shù)據(jù)庫文件。 說明: 主數(shù)據(jù)庫文件擴(kuò)展名為.mdf,表示Main Data File;

    2024年02月01日
    瀏覽(35)
  • 學(xué)習(xí)筆記-MySql數(shù)據(jù)庫介紹與連接

    學(xué)習(xí)筆記-MySql數(shù)據(jù)庫介紹與連接

    一.MySQL數(shù)據(jù)庫介紹 MySQL是一個(gè)關(guān)系型數(shù)據(jù)庫管理系統(tǒng),在 WEB 應(yīng)用方面,MySQL是最好的 RDMS (Relational Database Management System,關(guān)系數(shù)據(jù)庫管理系統(tǒng)) 應(yīng)用軟件,它是由瑞典MySQL AB 公司開發(fā),目前屬于 Oracle 旗下產(chǎn)品,MySQL 是最流行的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)中的一個(gè)。 1.特點(diǎn) 開源,

    2024年01月19日
    瀏覽(29)
  • WPF實(shí)戰(zhàn)學(xué)習(xí)筆記08-創(chuàng)建數(shù)據(jù)庫

    創(chuàng)建文件夾 ./Context 創(chuàng)建文件 ./Context/BaseEnity.cs ./Context/Memo.cs ./Context/MyTodoContext.cs ./Context/Todo.cs ./Context/User.cs 創(chuàng)建數(shù)據(jù)對象 ./Context/BaseEnity.cs ./Context/Memo.cs ./Context/MyTodoContext.cs 創(chuàng)建數(shù)據(jù)庫DbSet ./Context/Todo.cs ./Context/User.cs 添加nuget包 Microsoft.EntityFrameworkCore.Design Shared design-time co

    2024年02月16日
    瀏覽(46)
  • 【數(shù)據(jù)庫·關(guān)系數(shù)據(jù)庫標(biāo)準(zhǔn)語言SQL·學(xué)習(xí)筆記】Microsoft SQL Server數(shù)據(jù)庫的建立和刪除

    【數(shù)據(jù)庫·關(guān)系數(shù)據(jù)庫標(biāo)準(zhǔn)語言SQL·學(xué)習(xí)筆記】Microsoft SQL Server數(shù)據(jù)庫的建立和刪除

    開發(fā)環(huán)境:SQL Server Management Studio(SSMS) 利用數(shù)據(jù)庫對象資源管理器創(chuàng)建數(shù)據(jù)庫 (1)右擊對象資源管理器中的數(shù)據(jù)庫,選擇新建數(shù)據(jù)庫 (2)在新建數(shù)據(jù)庫界面輸入數(shù)據(jù)庫名稱 ,并選擇確定 利用CREAT DATABASE命令在SSM工具的新建查詢中創(chuàng)建數(shù)據(jù)庫 1.語法格式 CREATE DATABASE dat

    2024年02月08日
    瀏覽(34)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包