讀完這篇文章,就基本搞定了Redis數(shù)據(jù)庫
另外,Redis 也經(jīng)常用來做分布式鎖。Redis 提供了多種數(shù)據(jù)類型來支持不同的業(yè)務(wù)場景。
除此之外,Redis 支持事務(wù) 、持久化、LUA 腳本、LRU 驅(qū)動(dòng)事件、多種集群方案。
本文將從以下幾個(gè)方面全面解讀 Redis:
- 為什么要用 Redis / 為什么要用緩存
- 為什么要用 Redis 而不用 map/guava 做緩存
- Redis 和 Memcached 的區(qū)別
- Redis 常見數(shù)據(jù)結(jié)構(gòu)以及使用場景分析
- Redis 設(shè)置過期時(shí)間
- Redis 內(nèi)存淘汰機(jī)制
- Redis 持久化機(jī)制(怎么保證 Redis 掛掉之后再重啟數(shù)據(jù)可以進(jìn)行恢復(fù))
- Redis 事務(wù)
- 緩存雪崩和緩存穿透問題解決方案
- 如何解決 Redis 的并發(fā)競爭 Key 問題
- 如何保證緩存與數(shù)據(jù)庫雙寫時(shí)的數(shù)據(jù)一致性
為什么要用 Redis / 為什么要用緩存?
主要從“高性能”和“高并發(fā)”這兩點(diǎn)來看待這個(gè)問題。
高性能
假如用戶第一次訪問數(shù)據(jù)庫中的某些數(shù)據(jù)。這個(gè)過程會(huì)比較慢,因?yàn)槭菑挠脖P上讀取的。
將該用戶訪問的數(shù)據(jù)存在緩存中,這樣下一次再訪問這些數(shù)據(jù)的時(shí)候就可以直接從緩存中獲取了。
操作緩存就是直接操作內(nèi)存,所以速度相當(dāng)快。如果數(shù)據(jù)庫中的對(duì)應(yīng)數(shù)據(jù)改變了之后,同步改變緩存中相應(yīng)的數(shù)據(jù)即可!
高并發(fā)

直接操作緩存能夠承受的請(qǐng)求是遠(yuǎn)遠(yuǎn)大于直接訪問數(shù)據(jù)庫的,所以我們可以考慮把數(shù)據(jù)庫中的部分?jǐn)?shù)據(jù)轉(zhuǎn)移到緩存中去,這樣用戶的一部分請(qǐng)求會(huì)直接到緩存這里而不用經(jīng)過數(shù)據(jù)庫。
為什么要用 Redis 而不用 map/guava 做緩存
緩存分為本地緩存和分布式緩存。以 Java 為例,使用自帶的 map 或者 guava 實(shí)現(xiàn)的是本地緩存,最主要的特點(diǎn)是輕量以及快速,生命周期隨著 JVM 的銷毀而結(jié)束。
并且在多實(shí)例的情況下,每個(gè)實(shí)例都需要各自保存一份緩存,緩存不具有一致性。
使用 Redis 或 Memcached 之類的稱為分布式緩存,在多實(shí)例的情況下,各實(shí)例共用一份緩存數(shù)據(jù),緩存具有一致性。
缺點(diǎn)是需要保持 Redis 或 Memcached 服務(wù)的高可用,整個(gè)程序架構(gòu)上較為復(fù)雜。
Redis 和 Memcached 的區(qū)別
現(xiàn)在公司一般都是用 Redis 來實(shí)現(xiàn)緩存,而且 Redis 自身也越來越強(qiáng)大了!
對(duì)于 Redis 和 Memcached 我總結(jié)了下面四點(diǎn):
- Redis 支持更豐富的數(shù)據(jù)類型(支持更復(fù)雜的應(yīng)用場景):Redis 不僅僅支持簡單的 K/V 類型的數(shù)據(jù),同時(shí)還提供 list、set、zset、hash 等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)。Memcache 支持簡單的數(shù)據(jù)類型 String。
- Redis 支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保持在磁盤中,重啟的時(shí)候可以再次加載進(jìn)行使用,而 Memecache 把數(shù)據(jù)全部存在內(nèi)存之中。
- 集群模式:Memcached 沒有原生的集群模式,需要依靠客戶端來實(shí)現(xiàn)往集群中分片寫入數(shù)據(jù);但是 Redis 目前是原生支持 Cluster 模式的。
- Memcached 是多線程,非阻塞 IO 復(fù)用的網(wǎng)絡(luò)模型;Redis 使用單線程的多路 IO 復(fù)用模型。
來自網(wǎng)絡(luò)上的一張對(duì)比圖,這里分享給大家:
Redis 常見數(shù)據(jù)結(jié)構(gòu)以及使用場景分析
String
常用命令:set、get、decr、incr、mget 等。
String 數(shù)據(jù)結(jié)構(gòu)是簡單的 Key-Value 類型,Value 其實(shí)不僅可以是 String,也可以是數(shù)字。常規(guī) Key-Value 緩存應(yīng)用;常規(guī)計(jì)數(shù):微博數(shù),粉絲數(shù)等。
Hash
常用命令: hget、hset、hgetall 等。
Hash 是一個(gè) String 類型的 Field 和 Value 的映射表,Hash 特別適合用于存儲(chǔ)對(duì)象。
后續(xù)操作的時(shí)候,你可以直接僅僅修改這個(gè)對(duì)象中的某個(gè)字段的值。比如我們可以 Hash 數(shù)據(jù)結(jié)構(gòu)來存儲(chǔ)用戶信息,商品信息等等。
比如下面我就用 Hash 類型存放了我本人的一些信息:
- key=JavaUser293847
- value={
- “id”: 1,
- “name”: “SnailClimb”,
- “age”: 22,
- “location”: “Wuhan, Hubei”
- }
List
常用命令:lpush、rpush、lpop、rpop、lrange 等。
List 就是鏈表,Redis List 的應(yīng)用場景非常多,也是 Redis 最重要的數(shù)據(jù)結(jié)構(gòu)之一。
比如微博的關(guān)注列表,粉絲列表,消息列表等功能都可以用 Redis 的 List 結(jié)構(gòu)來實(shí)現(xiàn)。
Redis List 的實(shí)現(xiàn)為一個(gè)雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內(nèi)存開銷。
另外可以通過 lrange 命令,就是從某個(gè)元素開始讀取多少個(gè)元素,可以基于 List 實(shí)現(xiàn)分頁查詢。
這是很棒的一個(gè)功能,基于 Redis 實(shí)現(xiàn)簡單的高性能分頁,可以做類似微博那種下拉不斷分頁的東西(一頁一頁的往下走),性能高。
Set
常用命令:sadd、spop、smembers、sunion 等。
Set 對(duì)外提供的功能與 List 類似是一個(gè)列表的功能,特殊之處在于 Set 是可以自動(dòng)排重的。
當(dāng)你需要存儲(chǔ)一個(gè)列表數(shù)據(jù),又不希望出現(xiàn)重復(fù)數(shù)據(jù)時(shí),Set 是一個(gè)很好的選擇。
并且 Set 提供了判斷某個(gè)成員是否在一個(gè) Set 集合內(nèi)的重要接口,這個(gè)也是 List 所不能提供的。你可以基于 Set 輕易實(shí)現(xiàn)交集、并集、差集的操作。
比如:在微博應(yīng)用中,可以將一個(gè)用戶所有的關(guān)注人存在一個(gè)集合中,將其所有粉絲存在一個(gè)集合。Redis 可以非常方便的實(shí)現(xiàn)如共同關(guān)注、共同粉絲、共同喜好等功能。
這個(gè)過程也就是求交集的過程,具體命令如下:
- sinterstore key1 key2 key3 將交集存在key1內(nèi)
Sorted Set
常用命令:zadd、zrange、zrem、zcard 等。
和 Set 相比,Sorted Set 增加了一個(gè)權(quán)重參數(shù) Score,使得集合中的元素能夠按 Score 進(jìn)行有序排列。
舉例:在直播系統(tǒng)中,實(shí)時(shí)排行信息包含直播間在線用戶列表,各種禮物排行榜,彈幕消息(可以理解為按消息維度的消息排行榜)等信息,適合使用 Redis 中的 Sorted Set 結(jié)構(gòu)進(jìn)行存儲(chǔ)。
Redis 設(shè)置過期時(shí)間
Redis 中有個(gè)設(shè)置過期時(shí)間的功能,即對(duì)存儲(chǔ)在 Redis 數(shù)據(jù)庫中的值可以設(shè)置一個(gè)過期時(shí)間。作為一個(gè)緩存數(shù)據(jù)庫,這是非常實(shí)用的。
如我們一般項(xiàng)目中的 Token 或者一些登錄信息,尤其是短信驗(yàn)證碼都是有時(shí)間限制的,按照傳統(tǒng)的數(shù)據(jù)庫處理方式,一般都是自己判斷過期,這樣無疑會(huì)嚴(yán)重影響項(xiàng)目性能。
我們 Set Key 的時(shí)候,都可以給一個(gè) Expire Time,就是過期時(shí)間,通過過期時(shí)間我們可以指定這個(gè) Key 可以存活的時(shí)間。
如果你設(shè)置了一批 Key 只能存活 1 個(gè)小時(shí),那么接下來 1 小時(shí)后,Redis 是怎么對(duì)這批 Key 進(jìn)行刪除的?
答案是:定期刪除+惰性刪除。通過名字大概就能猜出這兩個(gè)刪除方式的意思了:
- 定期刪除:Redis 默認(rèn)是每隔 100ms 就隨機(jī)抽取一些設(shè)置了過期時(shí)間的 Key,檢查其是否過期,如果過期就刪除。
注意這里是隨機(jī)抽取的。為什么要隨機(jī)呢?你想一想假如 Redis 存了幾十萬個(gè) Key ,每隔 100ms 就遍歷所有的設(shè)置過期時(shí)間的 Key 的話,就會(huì)給 CPU 帶來很大的負(fù)載!
- 惰性刪除 :定期刪除可能會(huì)導(dǎo)致很多過期 Key 到了時(shí)間并沒有被刪除掉。所以就有了惰性刪除。
假如你的過期 Key,靠定期刪除沒有被刪除掉,還停留在內(nèi)存里,除非你的系統(tǒng)去查一下那個(gè) Key,才會(huì)被 Redis 給刪除掉。這就是所謂的惰性刪除,也是夠懶的哈!
但是僅僅通過設(shè)置過期時(shí)間還是有問題的。我們想一下:如果定期刪除漏掉了很多過期 Key,然后你也沒及時(shí)去查,也就沒走惰性刪除,此時(shí)會(huì)怎么樣?
如果大量過期 Key 堆積在內(nèi)存里,導(dǎo)致 Redis 內(nèi)存塊耗盡了。怎么解決這個(gè)問題呢?
Redis 內(nèi)存淘汰機(jī)制
MySQL 里有 2000w 數(shù)據(jù),Redis 中只存 20w 的數(shù)據(jù),如何保證 Redis 中的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)?
Redis 配置文件 redis.conf 中有相關(guān)注釋,我這里就不貼了,大家可以自行查閱或者通過這個(gè)網(wǎng)址查看:http://download.redis.io/redis-stable/redis.conf
Redis 提供 6 種數(shù)據(jù)淘汰策略:
- volatile-lru:從已設(shè)置過期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中挑選最近最少使用的數(shù)據(jù)淘汰。
- volatile-ttl:從已設(shè)置過期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中挑選將要過期的數(shù)據(jù)淘汰。
- volatile-random:從已設(shè)置過期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中任意選擇數(shù)據(jù)淘汰。
- allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間中,移除最近最少使用的key(這個(gè)是最常用的)。
- allkeys-random:從數(shù)據(jù)集(server.db[i].dict)中任意選擇數(shù)據(jù)淘汰。
- no-enviction:禁止驅(qū)逐數(shù)據(jù),也就是說當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),新寫入操作會(huì)報(bào)錯(cuò)。這個(gè)應(yīng)該沒人使用吧!
Redis 持久化機(jī)制
怎么保證 Redis 掛掉之后再重啟數(shù)據(jù)可以進(jìn)行恢復(fù)?很多時(shí)候我們需要持久化數(shù)據(jù)也就是將內(nèi)存中的數(shù)據(jù)寫入到硬盤里面。
大部分原因是為了之后重用數(shù)據(jù)(比如重啟機(jī)器、機(jī)器故障之后恢復(fù)數(shù)據(jù)),或者是為了防止系統(tǒng)故障而將數(shù)據(jù)備份到一個(gè)遠(yuǎn)程位置。
Redis 不同于 Memcached 的很重要一點(diǎn)就是,Redis 支持持久化,而且支持兩種不同的持久化操作。
Redis 的一種持久化方式叫快照(snapshotting,RDB),另一種方式是只追加文件(append-only file,AOF)。
這兩種方法各有千秋,下面我會(huì)詳細(xì)講這兩種持久化方法是什么,怎么用,如何選擇適合自己的持久化方法。
快照(snapshotting)持久化(RDB)
Redis 可以通過創(chuàng)建快照來獲得存儲(chǔ)在內(nèi)存里面的數(shù)據(jù)在某個(gè)時(shí)間點(diǎn)上的副本。
Redis 創(chuàng)建快照之后,可以對(duì)快照進(jìn)行備份,可以將快照復(fù)制到其他服務(wù)器從而創(chuàng)建具有相同數(shù)據(jù)的服務(wù)器副本(Redis 主從結(jié)構(gòu),主要用來提高 Redis 性能),還可以將快照留在原地以便重啟服務(wù)器的時(shí)候使用。
快照持久化是 Redis 默認(rèn)采用的持久化方式,在 redis.conf 配置文件中默認(rèn)有此下配置:
- save 900 1 #在900秒(15分鐘)之后,如果至少有1個(gè)key發(fā)生變化,Redis就會(huì)自動(dòng)觸發(fā)BGSAVE命令創(chuàng)建快照。
- save 300 10 #在300秒(5分鐘)之后,如果至少有10個(gè)key發(fā)生變化,Redis就會(huì)自動(dòng)觸發(fā)BGSAVE命令創(chuàng)建快照。
- save 60 10000 #在60秒(1分鐘)之后,如果至少有10000個(gè)key發(fā)生變化,Redis就會(huì)自動(dòng)觸發(fā)BGSAVE命令創(chuàng)建快照。
AOF(append-only file)持久化
與快照持久化相比,AOF 持久化的實(shí)時(shí)性更好,因此已成為主流的持久化方案。
默認(rèn)情況下 Redis 沒有開啟 AOF(append only file)方式的持久化,可以通過 appendonly 參數(shù)開啟:
- appendonly yes
開啟 AOF 持久化后每執(zhí)行一條會(huì)更改 Redis 中的數(shù)據(jù)的命令,Redis 就會(huì)將該命令寫入硬盤中的 AOF 文件。
AOF 文件的保存位置和 RDB 文件的位置相同,都是通過 dir 參數(shù)設(shè)置的,默認(rèn)的文件名是 appendonly.aof。
在 Redis 的配置文件中存在三種不同的 AOF 持久化方式,它們分別是:
- appendfsync always #每次有數(shù)據(jù)修改發(fā)生時(shí)都會(huì)寫入AOF文件,這樣會(huì)嚴(yán)重降低Redis的速度
- appendfsync everysec #每秒鐘同步一次,顯示地將多個(gè)寫命令同步到硬盤
- appendfsync no #讓操作系統(tǒng)決定何時(shí)進(jìn)行同步
為了兼顧數(shù)據(jù)和寫入性能,用戶可以考慮 appendfsync everysec 選項(xiàng) ,讓 Redis 每秒同步一次 AOF 文件,Redis 性能幾乎沒受到任何影響。
而且這樣即使出現(xiàn)系統(tǒng)崩潰,用戶最多只會(huì)丟失一秒之內(nèi)產(chǎn)生的數(shù)據(jù)。當(dāng)硬盤忙于執(zhí)行寫入操作的時(shí)候,Redis 還會(huì)優(yōu)雅的放慢自己的速度以便適應(yīng)硬盤的最大寫入速度。
Redis 4.0 對(duì)于持久化機(jī)制的優(yōu)化
Redis 4.0 開始支持 RDB 和 AOF 的混合持久化(默認(rèn)關(guān)閉,可以通過配置項(xiàng) aof-use-rdb-preamble 開啟)。
如果把混合持久化打開,AOF 重寫的時(shí)候就直接把 RDB 的內(nèi)容寫到 AOF 文件開頭。
這樣做的好處是可以結(jié)合 RDB 和 AOF 的優(yōu)點(diǎn), 快速加載同時(shí)避免丟失過多的數(shù)據(jù)。
當(dāng)然缺點(diǎn)也是有的,AOF 里面的 RDB 部分是壓縮格式不再是 AOF 格式,可讀性較差。
補(bǔ)充內(nèi)容:AOF 重寫
AOF 重寫可以產(chǎn)生一個(gè)新的 AOF 文件,這個(gè)新的 AOF 文件和原有的 AOF 文件所保存的數(shù)據(jù)庫狀態(tài)一樣,但體積更小。
AOF 重寫是一個(gè)有歧義的名字,該功能是通過讀取數(shù)據(jù)庫中的鍵值對(duì)來實(shí)現(xiàn)的,程序無須對(duì)現(xiàn)有 AOF 文件進(jìn)行任伺讀入、分析或者寫入操作。
在執(zhí)行 BGREWRITEAOF 命令時(shí),Redis 服務(wù)器會(huì)維護(hù)一個(gè) AOF 重寫緩沖區(qū),該緩沖區(qū)會(huì)在子進(jìn)程創(chuàng)建新 AOF 文件期間,記錄服務(wù)器執(zhí)行的所有寫命令。
當(dāng)子進(jìn)程完成創(chuàng)建新 AOF 文件的工作之后,服務(wù)器會(huì)將重寫緩沖區(qū)中的所有內(nèi)容追加到新 AOF 文件的末尾,使得新舊兩個(gè) AOF 文件所保存的數(shù)據(jù)庫狀態(tài)一致。
最后,服務(wù)器用新的 AOF 文件替換舊的 AOF 文件,以此來完成 AOF 文件重寫操作。
Redis 事務(wù)
Redis 通過 MULTI、EXEC、WATCH 等命令來實(shí)現(xiàn)事務(wù)(transaction)功能。
事務(wù)提供了一種將多個(gè)命令請(qǐng)求打包,然后一次性、按順序地執(zhí)行多個(gè)命令的機(jī)制。
并且在事務(wù)執(zhí)行期間,服務(wù)器不會(huì)中斷事務(wù)而改去執(zhí)行其他客戶端的命令請(qǐng)求,它會(huì)將事務(wù)中的所有命令都執(zhí)行完畢,然后才去處理其他客戶端的命令請(qǐng)求。
在傳統(tǒng)的關(guān)系式數(shù)據(jù)庫中,常常用 ACID 性質(zhì)來檢驗(yàn)事務(wù)功能的可靠性和安全性。
在 Redis 中,事務(wù)總是具有原子性(Atomicity)、一致性(Consistency)和隔離性(Isolation),并且當(dāng) Redis 運(yùn)行在某種特定的持久化模式下時(shí),事務(wù)也具有持久性(Durability)。
緩存雪崩和緩存穿透問題解決方案
緩存雪崩
簡介:緩存同一時(shí)間大面積的失效,所以,后面的請(qǐng)求都會(huì)落到數(shù)據(jù)庫上,造成數(shù)據(jù)庫短時(shí)間內(nèi)承受大量請(qǐng)求而崩掉。
解決辦法:
- 事前:盡量保證整個(gè) Redis 集群的高可用性,發(fā)現(xiàn)機(jī)器宕機(jī)盡快補(bǔ)上。選擇合適的內(nèi)存淘汰策略。
- 事中:本地 Ehcache 緩存 + Hystrix 限流&降級(jí),避免 MySQL 崩掉。
- 事后:利用 Redis 持久化機(jī)制保存的數(shù)據(jù)盡快恢復(fù)緩存。
緩存穿透
簡介:一般是黑客故意去請(qǐng)求緩存中不存在的數(shù)據(jù),導(dǎo)致所有的請(qǐng)求都落到數(shù)據(jù)庫上,造成數(shù)據(jù)庫短時(shí)間內(nèi)承受大量請(qǐng)求而崩掉。
解決辦法:有很多種方法可以有效地解決緩存穿透問題,最常見的則是采用布隆過濾器,將所有可能存在的數(shù)據(jù)哈希到一個(gè)足夠大的 bitmap 中。
一個(gè)一定不存在的數(shù)據(jù)會(huì)被這個(gè) bitmap 攔截掉,從而避免了對(duì)底層存儲(chǔ)系統(tǒng)的查詢壓力。
另外也有一個(gè)更為簡單粗暴的方法(我們采用的就是這種),如果一個(gè)查詢返回的數(shù)據(jù)為空(不管是數(shù)據(jù)不存在,還是系統(tǒng)故障),我們?nèi)匀话堰@個(gè)空結(jié)果進(jìn)行緩存,但它的過期時(shí)間會(huì)很短,最長不超過五分鐘。
如何解決 Redis 的并發(fā)競爭 Key 問題
所謂 Redis 的并發(fā)競爭 Key 的問題也就是多個(gè)系統(tǒng)同時(shí)對(duì)一個(gè) Key 進(jìn)行操作,但是最后執(zhí)行的順序和我們期望的順序不同,這樣也就導(dǎo)致了結(jié)果的不同!
推薦一種方案:分布式鎖(ZooKeeper 和 Redis 都可以實(shí)現(xiàn)分布式鎖)。(如果不存在 Redis 的并發(fā)競爭 Key 問題,不要使用分布式鎖,這樣會(huì)影響性能)
基于 ZooKeeper 臨時(shí)有序節(jié)點(diǎn)可以實(shí)現(xiàn)的分布式鎖。大致思想為:每個(gè)客戶端對(duì)某個(gè)方法加鎖時(shí),在 ZooKeeper 上的與該方法對(duì)應(yīng)的指定節(jié)點(diǎn)的目錄下,生成一個(gè)唯一的瞬時(shí)有序節(jié)點(diǎn)。
判斷是否獲取鎖的方式很簡單,只需要判斷有序節(jié)點(diǎn)中序號(hào)最小的一個(gè)。 當(dāng)釋放鎖的時(shí)候,只需將這個(gè)瞬時(shí)節(jié)點(diǎn)刪除即可。
同時(shí),其可以避免服務(wù)宕機(jī)導(dǎo)致的鎖無法釋放,而產(chǎn)生的死鎖問題。完成業(yè)務(wù)流程后,刪除對(duì)應(yīng)的子節(jié)點(diǎn)釋放鎖。
在實(shí)踐中,當(dāng)然是以可靠性為主。所以首推 ZooKeeper。
如何保證緩存與數(shù)據(jù)庫雙寫時(shí)的數(shù)據(jù)一致性
你只要用緩存,就可能會(huì)涉及到緩存與數(shù)據(jù)庫雙存儲(chǔ)雙寫,你只要是雙寫,就一定會(huì)有數(shù)據(jù)一致性的問題,那么你如何解決一致性問題?
一般來說,就是如果你的系統(tǒng)不是嚴(yán)格要求緩存+數(shù)據(jù)庫必須一致性的話,緩存可以稍微的跟數(shù)據(jù)庫偶爾有不一致的情況。
最好不要做這個(gè)方案,讀請(qǐng)求和寫請(qǐng)求串行化,串到一個(gè)內(nèi)存隊(duì)列里去,這樣就可以保證一定不會(huì)出現(xiàn)不一致的情況。
串行化之后,就會(huì)導(dǎo)致系統(tǒng)的吞吐量會(huì)大幅度的降低,用比正常情況下多幾倍的機(jī)器去支撐線上的一個(gè)請(qǐng)求。
參考文章:
- https://segmentfault.com/q/1010000009106416
- Redis設(shè)計(jì)與實(shí)現(xiàn)(第二版)
- https://www.jianshu.com/p/8bddd381de06
- https://blog.csdn.net/zeb_perfect/article/details/54135506
- Java工程師面試突擊第1季(可能是史上最好的Java面試突擊課程)-中華石杉老師。鏈接: https://pan.baidu.com/s/18pp6g1xKVGCfUATf_nMrOA,密碼:5i58
福利來啦
請(qǐng)結(jié)合自身情況談?wù)勥\(yùn)用 Redis 中的難點(diǎn)。掃描下方二維碼,關(guān)注51CTO技術(shù)棧公眾號(hào)。歡迎在技術(shù)棧微信公眾號(hào)留言探討。小編將選出留言最精彩的 10 名網(wǎng)友,送出《PHP 高性能開發(fā):基礎(chǔ)、框架與項(xiàng)目實(shí)戰(zhàn)》圖書一本~活動(dòng)截止時(shí)間 10 月 4 日十二時(shí)整,特別鳴謝機(jī)械工業(yè)出版社為本次活動(dòng)提供的圖書贊助。等不及送書的小伙伴,可以點(diǎn)擊閱讀原文直接購買。
書籍簡介
本書分為 3 篇:第 1 篇基礎(chǔ)入門篇,包括 PHP 快速入門、虛擬機(jī)與個(gè)性化開發(fā)環(huán)境搭建、Git 版本控制、高效團(tuán)隊(duì)合作、PHP Storm 技巧、Composer 包管理工具等內(nèi)容。第 2 篇框架進(jìn)階篇,分別介紹了前端框架 Bootstrap 和后端框架 ThinkPHP5,幫助開發(fā)者掌握快速開發(fā)項(xiàng)目的方法。第 3 篇項(xiàng)目實(shí)戰(zhàn)篇,帶領(lǐng)開發(fā)者完成了一個(gè)基本的內(nèi)容管理框架,并在此基礎(chǔ)上實(shí)現(xiàn)了計(jì)劃任務(wù)的可視化管理和基于 Redis 隊(duì)列的商城搶購系統(tǒng)。