在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Redis是什么

數(shù)據(jù)分析與開發(fā) ? 來源:業(yè)余草 ? 作者:業(yè)余草 ? 2021-02-04 16:09 ? 次閱讀

今天,“我”不自量力的面試了某大廠的 Java 開發(fā)崗位,迎面走來一位風(fēng)塵仆仆的中年男子,手里拿著屏幕還亮著的 Mac。他沖著我禮貌的笑了笑,然后說了句“不好意思,讓你久等了”,然后示意我坐下,說:“我們開始吧,看了你的簡歷,覺得你對 Redis 應(yīng)該掌握的不錯(cuò),我們今天就來討論下 Redis……”。我想:“來就來,兵來將擋水來土掩”。

Redis 是什么

面試官:你先來說下 Redis 是什么吧!

我:(這不就是總結(jié)下 Redis 的定義和特點(diǎn)嘛)Redis 是 C 語言開發(fā)的一個(gè)開源的(遵從 BSD 協(xié)議)高性能鍵值對(key-value)的內(nèi)存數(shù)據(jù)庫,可以用作數(shù)據(jù)庫、緩存、消息中間件等。

它是一種 NoSQL(not-only sql,泛指非關(guān)系型數(shù)據(jù)庫)的數(shù)據(jù)庫。

我頓了一下,接著說,Redis 作為一個(gè)內(nèi)存數(shù)據(jù)庫:

性能優(yōu)秀,數(shù)據(jù)在內(nèi)存中,讀寫速度非常快,支持并發(fā) 10W QPS。

單進(jìn)程單線程,是線程安全的,采用 IO 多路復(fù)用機(jī)制。

豐富的數(shù)據(jù)類型,支持字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。

支持?jǐn)?shù)據(jù)持久化。

可以將內(nèi)存中數(shù)據(jù)保存在磁盤中,重啟時(shí)加載。

主從復(fù)制,哨兵,高可用。

可以用作分布式鎖。

可以作為消息中間件使用,支持發(fā)布訂閱。

五種數(shù)據(jù)類型

面試官:總結(jié)的不錯(cuò),看來是早有準(zhǔn)備啊。剛來聽你提到 Redis 支持五種數(shù)據(jù)類型,那你能簡單說下這五種數(shù)據(jù)類型嗎?

我:當(dāng)然可以,但是在說之前,我覺得有必要先來了解下 Redis 內(nèi)部內(nèi)存管理是如何描述這 5 種數(shù)據(jù)類型的。

說著,我拿著筆給面試官畫了一張圖:

727fac44-584b-11eb-8b86-12bb97331649.jpg

我:首先 Redis 內(nèi)部使用一個(gè) redisObject 對象來表示所有的 key 和 value。 redisObject 最主要的信息如上圖所示:type 表示一個(gè) value 對象具體是何種數(shù)據(jù)類型,encoding 是不同數(shù)據(jù)類型在 Redis 內(nèi)部的存儲方式。 比如:type=string 表示 value 存儲的是一個(gè)普通字符串,那么 encoding 可以是 raw 或者 int。

我頓了一下,接著說,下面我簡單說下 5 種數(shù)據(jù)類型:

①String 是 Redis 最基本的類型,可以理解成與 Memcached一模一樣的類型,一個(gè) Key 對應(yīng)一個(gè) Value。Value 不僅是 String,也可以是數(shù)字。

String 類型是二進(jìn)制安全的,意思是 Redis 的 String 類型可以包含任何數(shù)據(jù),比如 jpg 圖片或者序列化的對象。String 類型的值最大能存儲 512M。

②Hash是一個(gè)鍵值(key-value)的集合。Redis 的 Hash 是一個(gè) String 的 Key 和 Value 的映射表,Hash 特別適合存儲對象。常用命令:hget,hset,hgetall 等。

③List 列表是簡單的字符串列表,按照插入順序排序。可以添加一個(gè)元素到列表的頭部(左邊)或者尾部(右邊) 常用命令:lpush、rpush、lpop、rpop、lrange(獲取列表片段)等。 應(yīng)用場景:List 應(yīng)用場景非常多,也是 Redis 最重要的數(shù)據(jù)結(jié)構(gòu)之一,比如 Twitter 的關(guān)注列表,粉絲列表都可以用 List 結(jié)構(gòu)來實(shí)現(xiàn)。

數(shù)據(jù)結(jié)構(gòu):List 就是鏈表,可以用來當(dāng)消息隊(duì)列用。Redis 提供了 List 的 Push 和 Pop 操作,還提供了操作某一段的 API,可以直接查詢或者刪除某一段的元素。

實(shí)現(xiàn)方式:Redis List 的是實(shí)現(xiàn)是一個(gè)雙向鏈表,既可以支持反向查找和遍歷,更方便操作,不過帶來了額外的內(nèi)存開銷。 ④Set 是 String 類型的無序集合。集合是通過 hashtable 實(shí)現(xiàn)的。Set 中的元素是沒有順序的,而且是沒有重復(fù)的。常用命令:sdd、spop、smembers、sunion 等。

應(yīng)用場景:Redis Set 對外提供的功能和 List 一樣是一個(gè)列表,特殊之處在于 Set 是自動(dòng)去重的,而且 Set 提供了判斷某個(gè)成員是否在一個(gè) Set 集合中。

⑤Zset 和 Set 一樣是 String 類型元素的集合,且不允許重復(fù)的元素。常用命令:zadd、zrange、zrem、zcard 等。

使用場景:Sorted Set 可以通過用戶額外提供一個(gè)優(yōu)先級(score)的參數(shù)來為成員排序,并且是插入有序的,即自動(dòng)排序。

當(dāng)你需要一個(gè)有序的并且不重復(fù)的集合列表,那么可以選擇 Sorted Set 結(jié)構(gòu)。

和 Set 相比,Sorted Set關(guān)聯(lián)了一個(gè) Double 類型權(quán)重的參數(shù) Score,使得集合中的元素能夠按照 Score 進(jìn)行有序排列,Redis 正是通過分?jǐn)?shù)來為集合中的成員進(jìn)行從小到大的排序。

實(shí)現(xiàn)方式:Redis Sorted Set 的內(nèi)部使用 HashMap 和跳躍表(skipList)來保證數(shù)據(jù)的存儲和有序,HashMap 里放的是成員到 Score 的映射。

而跳躍表里存放的是所有的成員,排序依據(jù)是 HashMap 里存的 Score,使用跳躍表的結(jié)構(gòu)可以獲得比較高的查找效率,并且在實(shí)現(xiàn)上比較簡單。

數(shù)據(jù)類型應(yīng)用場景總結(jié):

728c73f2-584b-11eb-8b86-12bb97331649.png

面試官:想不到你平時(shí)也下了不少工夫,那 Redis 緩存你一定用過的吧? 我:用過的。

面試官:那你跟我說下你是怎么用的?

我是結(jié)合 Spring Boot 使用的。一般有兩種方式,一種是直接通過 RedisTemplate 來使用,另一種是使用 Spring Cache 集成 Redis(也就是注解的方式)。

Redis 緩存

直接通過 RedisTemplate 來使用,使用 Spring Cache 集成 Redis pom.xml 中加入以下依賴:

org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2 org.springframework.boot spring-boot-starter-web org.springframework.session spring-session-data-redis org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test

spring-boot-starter-data-redis:在 Spring Boot 2.x 以后底層不再使用 Jedis,而是換成了 Lettuce。

commons-pool2:用作 Redis 連接池,如不引入啟動(dòng)會(huì)報(bào)錯(cuò)。

spring-session-data-redis:Spring Session 引入,用作共享 Session。

配置文件 application.yml 的配置:

server: port:8082 servlet: session: timeout:30ms spring: cache: type:redis redis: host:127.0.0.1 port:6379 password: #redis默認(rèn)情況下有16個(gè)分片,這里配置具體使用的分片,默認(rèn)為0 database:0 lettuce: pool: #連接池最大連接數(shù)(使用負(fù)數(shù)表示沒有限制),默認(rèn)8 max-active:100

創(chuàng)建實(shí)體類 User.java:

publicclassUserimplementsSerializable{ privatestaticfinallongserialVersionUID=662692455422902539L; privateIntegerid; privateStringname; privateIntegerage; publicUser(){ } publicUser(Integerid,Stringname,Integerage){ this.id=id; this.name=name; this.age=age; } publicIntegergetId(){ returnid; } publicvoidsetId(Integerid){ this.id=id; } publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } publicIntegergetAge(){ returnage; } publicvoidsetAge(Integerage){ this.age=age; } @Override publicStringtoString(){ return"User{"+ "id="+id+ ",name='"+name+'''+ ",age="+age+ '}'; } }

RedisTemplate 的使用方式

默認(rèn)情況下的模板只能支持 RedisTemplate,也就是只能存入字符串,所以自定義模板很有必要。

添加配置類 RedisCacheConfig.java:

@Configuration @AutoConfigureAfter(RedisAutoConfiguration.class) publicclassRedisCacheConfig{ @Bean publicRedisTemplateredisCacheTemplate(LettuceConnectionFactoryconnectionFactory){ RedisTemplatetemplate=newRedisTemplate<>(); template.setKeySerializer(newStringRedisSerializer()); template.setValueSerializer(newGenericJackson2JsonRedisSerializer()); template.setConnectionFactory(connectionFactory); returntemplate; } }

測試類:

@RestController @RequestMapping("/user") publicclassUserController{ publicstaticLoggerlogger=LogManager.getLogger(UserController.class); @Autowired privateStringRedisTemplatestringRedisTemplate; @Autowired privateRedisTemplateredisCacheTemplate; @RequestMapping("/test") publicvoidtest(){ redisCacheTemplate.opsForValue().set("userkey",newUser(1,"張三",25)); Useruser=(User)redisCacheTemplate.opsForValue().get("userkey"); logger.info("當(dāng)前獲取對象:{}",user.toString()); }

然后在瀏覽器訪問,觀察后臺日志 http://localhost:8082/user/test

72af1f1a-584b-11eb-8b86-12bb97331649.jpg

使用 Spring Cache 集成 Redis

Spring Cache 具備很好的靈活性,不僅能夠使用 SPEL(spring expression language)來定義緩存的 Key 和各種 Condition,還提供了開箱即用的緩存臨時(shí)存儲方案,也支持和主流的專業(yè)緩存如 EhCache、Redis、Guava 的集成。 定義接口 UserService.java:

publicinterfaceUserService{ Usersave(Useruser); voiddelete(intid); Userget(Integerid); }

接口實(shí)現(xiàn)類 UserServiceImpl.java:

@Service publicclassUserServiceImplimplementsUserService{ publicstaticLoggerlogger=LogManager.getLogger(UserServiceImpl.class); privatestaticMapuserMap=newHashMap<>(); static{ userMap.put(1,newUser(1,"肖戰(zhàn)",25)); userMap.put(2,newUser(2,"王一博",26)); userMap.put(3,newUser(3,"楊紫",24)); } @CachePut(value="user",key="#user.id") @Override publicUsersave(Useruser){ userMap.put(user.getId(),user); logger.info("進(jìn)入save方法,當(dāng)前存儲對象:{}",user.toString()); returnuser; } @CacheEvict(value="user",key="#id") @Override publicvoiddelete(intid){ userMap.remove(id); logger.info("進(jìn)入delete方法,刪除成功"); } @Cacheable(value="user",key="#id") @Override publicUserget(Integerid){ logger.info("進(jìn)入get方法,當(dāng)前獲取對象:{}",userMap.get(id)==null?null:userMap.get(id).toString()); returnuserMap.get(id); } }

為了方便演示數(shù)據(jù)庫的操作,這里直接定義了一個(gè) Map userMap。 這里的核心是三個(gè)注解:

@Cachable

@CachePut

@CacheEvict

測試類:UserController

@RestController @RequestMapping("/user") publicclassUserController{ publicstaticLoggerlogger=LogManager.getLogger(UserController.class); @Autowired privateStringRedisTemplatestringRedisTemplate; @Autowired privateRedisTemplateredisCacheTemplate; @Autowired privateUserServiceuserService; @RequestMapping("/test") publicvoidtest(){ redisCacheTemplate.opsForValue().set("userkey",newUser(1,"張三",25)); Useruser=(User)redisCacheTemplate.opsForValue().get("userkey"); logger.info("當(dāng)前獲取對象:{}",user.toString()); } @RequestMapping("/add") publicvoidadd(){ Useruser=userService.save(newUser(4,"李現(xiàn)",30)); logger.info("添加的用戶信息:{}",user.toString()); } @RequestMapping("/delete") publicvoiddelete(){ userService.delete(4); } @RequestMapping("/get/{id}") publicvoidget(@PathVariable("id")StringidStr)throwsException{ if(StringUtils.isBlank(idStr)){ thrownewException("id為空"); } Integerid=Integer.parseInt(idStr); Useruser=userService.get(id); logger.info("獲取的用戶信息:{}",user.toString()); } }

用緩存要注意,啟動(dòng)類要加上一個(gè)注解開啟緩存:

@SpringBootApplication(exclude=DataSourceAutoConfiguration.class) @EnableCaching publicclassApplication{ publicstaticvoidmain(String[]args){ SpringApplication.run(Application.class,args); } }

①先調(diào)用添加接口:http://localhost:8082/user/add

72d8a2cc-584b-11eb-8b86-12bb97331649.jpg

②再調(diào)用查詢接口,查詢 id=4 的用戶信息:

72f5b6be-584b-11eb-8b86-12bb97331649.jpg

可以看出,這里已經(jīng)從緩存中獲取數(shù)據(jù)了,因?yàn)樯弦徊?add 方法已經(jīng)把 id=4 的用戶數(shù)據(jù)放入了 Redis 緩存 3、調(diào)用刪除方法,刪除 id=4 的用戶信息,同時(shí)清除緩存:

73049ba2-584b-11eb-8b86-12bb97331649.jpg

④再次調(diào)用查詢接口,查詢 id=4 的用戶信息:

7320983e-584b-11eb-8b86-12bb97331649.jpg

沒有了緩存,所以進(jìn)入了 get 方法,從 userMap 中獲取。

緩存注解

①@Cacheable

根據(jù)方法的請求參數(shù)對其結(jié)果進(jìn)行緩存:

Key:緩存的 Key,可以為空,如果指定要按照 SPEL 表達(dá)式編寫,如果不指定,則按照方法的所有參數(shù)進(jìn)行組合。

Value:緩存的名稱,必須指定至少一個(gè)(如 @Cacheable (value='user')或者 @Cacheable(value={'user1','user2'}))

Condition:緩存的條件,可以為空,使用 SPEL 編寫,返回 true 或者 false,只有為 true 才進(jìn)行緩存。

②@CachePut

根據(jù)方法的請求參數(shù)對其結(jié)果進(jìn)行緩存,和 @Cacheable 不同的是,它每次都會(huì)觸發(fā)真實(shí)方法的調(diào)用。參數(shù)描述見上。

③@CacheEvict

根據(jù)條件對緩存進(jìn)行清空:

Key:同上。

Value:同上。

Condition:同上。

allEntries:是否清空所有緩存內(nèi)容,缺省為 false,如果指定為 true,則方法調(diào)用后將立即清空所有緩存。

beforeInvocation:是否在方法執(zhí)行前就清空,缺省為 false,如果指定為 true,則在方法還沒有執(zhí)行的時(shí)候就清空緩存。缺省情況下,如果方法執(zhí)行拋出異常,則不會(huì)清空緩存。

緩存問題

面試官:看了一下你的 Demo,簡單易懂。那你在實(shí)際項(xiàng)目中使用緩存有遇到什么問題或者會(huì)遇到什么問題你知道嗎?

我:緩存和數(shù)據(jù)庫數(shù)據(jù)一致性問題:分布式環(huán)境下非常容易出現(xiàn)緩存和數(shù)據(jù)庫間數(shù)據(jù)一致性問題,針對這一點(diǎn),如果項(xiàng)目對緩存的要求是強(qiáng)一致性的,那么就不要使用緩存。

我們只能采取合適的策略來降低緩存和數(shù)據(jù)庫間數(shù)據(jù)不一致的概率,而無法保證兩者間的強(qiáng)一致性。

合適的策略包括合適的緩存更新策略,更新數(shù)據(jù)庫后及時(shí)更新緩存、緩存失敗時(shí)增加重試機(jī)制。 面試官:Redis 雪崩了解嗎?

我:我了解的,目前電商首頁以及熱點(diǎn)數(shù)據(jù)都會(huì)去做緩存,一般緩存都是定時(shí)任務(wù)去刷新,或者查不到之后去更新緩存的,定時(shí)任務(wù)刷新就有一個(gè)問題。

舉個(gè)栗子:如果首頁所有 Key 的失效時(shí)間都是 12 小時(shí),中午 12 點(diǎn)刷新的,我零點(diǎn)有個(gè)大促活動(dòng)大量用戶涌入,假設(shè)每秒 6000 個(gè)請求,本來緩存可以抗住每秒 5000 個(gè)請求,但是緩存中所有 Key 都失效了。

此時(shí) 6000 個(gè)/秒的請求全部落在了數(shù)據(jù)庫上,數(shù)據(jù)庫必然扛不住,真實(shí)情況可能 DBA 都沒反應(yīng)過來直接掛了。

此時(shí),如果沒什么特別的方案來處理,DBA 很著急,重啟數(shù)據(jù)庫,但是數(shù)據(jù)庫立馬又被新流量給打死了。這就是我理解的緩存雪崩。

我心想:同一時(shí)間大面積失效,瞬間 Redis 跟沒有一樣,那這個(gè)數(shù)量級別的請求直接打到數(shù)據(jù)庫幾乎是災(zāi)難性的。

你想想如果掛的是一個(gè)用戶服務(wù)的庫,那其他依賴他的庫所有接口幾乎都會(huì)報(bào)錯(cuò)。

如果沒做熔斷等策略基本上就是瞬間掛一片的節(jié)奏,你怎么重啟用戶都會(huì)把你打掛,等你重啟好的時(shí)候,用戶早睡覺去了,臨睡之前,罵罵咧咧“什么垃圾產(chǎn)品”。 面試官摸摸了自己的頭發(fā):嗯,還不錯(cuò),那這種情況你都是怎么應(yīng)對的?

我:處理緩存雪崩簡單,在批量往 Redis 存數(shù)據(jù)的時(shí)候,把每個(gè) Key 的失效時(shí)間都加個(gè)隨機(jī)值就好了,這樣可以保證數(shù)據(jù)不會(huì)再同一時(shí)間大面積失效。

setRedis(key,value,time+Math.random()*10000);

如果 Redis 是集群部署,將熱點(diǎn)數(shù)據(jù)均勻分布在不同的 Redis 庫中也能避免全部失效。

或者設(shè)置熱點(diǎn)數(shù)據(jù)永不過期,有更新操作就更新緩存就好了(比如運(yùn)維更新了首頁商品,那你刷下緩存就好了,不要設(shè)置過期時(shí)間),電商首頁的數(shù)據(jù)也可以用這個(gè)操作,保險(xiǎn)。

面試官:那你了解緩存穿透和擊穿么,可以說說他們跟雪崩的區(qū)別嗎?

我:嗯,了解,先說下緩存穿透吧,緩存穿透是指緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù),而用戶(黑客)不斷發(fā)起請求。

舉個(gè)栗子:我們數(shù)據(jù)庫的 id 都是從 1 自增的,如果發(fā)起 id=-1 的數(shù)據(jù)或者 id 特別大不存在的數(shù)據(jù),這樣的不斷攻擊導(dǎo)致數(shù)據(jù)庫壓力很大,嚴(yán)重會(huì)擊垮數(shù)據(jù)庫。

我又接著說:至于緩存擊穿嘛,這個(gè)跟緩存雪崩有點(diǎn)像,但是又有一點(diǎn)不一樣,緩存雪崩是因?yàn)榇竺娣e的緩存失效,打崩了 DB。

而緩存擊穿不同的是緩存擊穿是指一個(gè) Key 非常熱點(diǎn),在不停地扛著大量的請求,大并發(fā)集中對這一個(gè)點(diǎn)進(jìn)行訪問,當(dāng)這個(gè) Key 在失效的瞬間,持續(xù)的大并發(fā)直接落到了數(shù)據(jù)庫上,就在這個(gè) Key 的點(diǎn)上擊穿了緩存。 面試官露出欣慰的眼光:那他們分別怎么解決?

我:緩存穿透我會(huì)在接口層增加校驗(yàn),比如用戶鑒權(quán),參數(shù)做校驗(yàn),不合法的校驗(yàn)直接 return,比如 id 做基礎(chǔ)校驗(yàn),id<=0 直接攔截。 ?面試官:那你還有別的方法嗎?

我:我記得 Redis 里還有一個(gè)高級用法布隆過濾器(Bloom Filter)這個(gè)也能很好的預(yù)防緩存穿透的發(fā)生。

它的原理也很簡單,就是利用高效的數(shù)據(jù)結(jié)構(gòu)和算法快速判斷出你這個(gè) Key 是否在數(shù)據(jù)庫中存在,不存在你 return 就好了,存在你就去查 DB 刷新 KV 再 return。

緩存擊穿的話,設(shè)置熱點(diǎn)數(shù)據(jù)永不過期,或者加上互斥鎖就搞定了。作為暖男,代碼給你準(zhǔn)備好了,拿走不謝。

publicstaticStringgetData(Stringkey)throwsInterruptedException{ //從Redis查詢數(shù)據(jù) Stringresult=getDataByKV(key); //參數(shù)校驗(yàn) if(StringUtils.isBlank(result)){ try{ //獲得鎖 if(reenLock.tryLock()){ //去數(shù)據(jù)庫查詢 result=getDataByDB(key); //校驗(yàn) if(StringUtils.isNotBlank(result)){ //插進(jìn)緩存 setDataToKV(key,result); } }else{ //睡一會(huì)再拿 Thread.sleep(100L); result=getData(key); } }finally{ //釋放鎖 reenLock.unlock(); } } returnresult; }

面試官:嗯嗯,還不錯(cuò)。

Redis 為何這么快

面試官:Redis 作為緩存大家都在用,那 Redis 一定很快咯?

我:當(dāng)然了,官方提供的數(shù)據(jù)可以達(dá)到 100000+ 的 QPS(每秒內(nèi)的查詢次數(shù)),這個(gè)數(shù)據(jù)不比 Memcached 差!

面試官:Redis 這么快,它的“多線程模型”你了解嗎?(露出邪魅一笑)

我:您是想問 Redis 這么快,為什么還是單線程的吧。Redis 確實(shí)是單進(jìn)程單線程的模型,因?yàn)?Redis 完全是基于內(nèi)存的操作,CPU 不是 Redis 的瓶頸,Redis 的瓶頸最有可能是機(jī)器內(nèi)存的大小或者網(wǎng)絡(luò)帶寬。

既然單線程容易實(shí)現(xiàn),而且 CPU 不會(huì)成為瓶頸,那就順理成章的采用單線程的方案了(畢竟采用多線程會(huì)有很多麻煩)。

面試官:嗯,是的。那你能說說 Redis 是單線程的,為什么還能這么快嗎?

我:可以這么說吧,總結(jié)一下有如下四點(diǎn):

Redis 完全基于內(nèi)存,絕大部分請求是純粹的內(nèi)存操作,非常迅速,數(shù)據(jù)存在內(nèi)存中,類似于 HashMap,HashMap 的優(yōu)勢就是查找和操作的時(shí)間復(fù)雜度是 O(1)。

數(shù)據(jù)結(jié)構(gòu)簡單,對數(shù)據(jù)操作也簡單。

采用單線程,避免了不必要的上下文切換和競爭條件,不存在多線程導(dǎo)致的 CPU 切換,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有死鎖問題導(dǎo)致的性能消耗。

使用多路復(fù)用 IO 模型,非阻塞 IO。

Redis 和 Memcached 的區(qū)別

面試官:嗯嗯,說的很詳細(xì)。那你為什么選擇 Redis 的緩存方案而不用 Memcached 呢? 我:原因有如下四點(diǎn):

存儲方式上:Memcache 會(huì)把數(shù)據(jù)全部存在內(nèi)存之中,斷電后會(huì)掛掉,數(shù)據(jù)不能超過內(nèi)存大小。Redis 有部分?jǐn)?shù)據(jù)存在硬盤上,這樣能保證數(shù)據(jù)的持久性。

數(shù)據(jù)支持類型上:Memcache 對數(shù)據(jù)類型的支持簡單,只支持簡單的 key-value,,而 Redis 支持五種數(shù)據(jù)類型。

使用底層模型不同:它們之間底層實(shí)現(xiàn)方式以及與客戶端之間通信的應(yīng)用協(xié)議不一樣。Redis 直接自己構(gòu)建了 VM 機(jī)制,因?yàn)橐话愕南到y(tǒng)調(diào)用系統(tǒng)函數(shù)的話,會(huì)浪費(fèi)一定的時(shí)間去移動(dòng)和請求。

Value 的大小:Redis 可以達(dá)到 1GB,而 Memcache 只有 1MB。

淘汰策略

面試官:那你說說你知道的 Redis 的淘汰策略有哪些?

我:Redis 有六種淘汰策略,如下圖:

73416e92-584b-11eb-8b86-12bb97331649.png

補(bǔ)充一下:Redis 4.0 加入了 LFU(least frequency use)淘汰策略,包括 volatile-lfu 和 allkeys-lfu,通過統(tǒng)計(jì)訪問頻率,將訪問頻率最少,即最不經(jīng)常使用的 KV 淘汰。

持久化

面試官:你對 Redis 的持久化機(jī)制了解嗎?能講一下嗎?

我:Redis 為了保證效率,數(shù)據(jù)緩存在了內(nèi)存中,但是會(huì)周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件中,以保證數(shù)據(jù)的持久化。

Redis 的持久化策略有兩種:

RDB:快照形式是直接把內(nèi)存中的數(shù)據(jù)保存到一個(gè) dump 的文件中,定時(shí)保存,保存策略。

AOF:把所有的對 Redis 的服務(wù)器進(jìn)行修改的命令都存到一個(gè)文件里,命令的集合。Redis 默認(rèn)是快照 RDB 的持久化方式。

當(dāng) Redis 重啟的時(shí)候,它會(huì)優(yōu)先使用 AOF 文件來還原數(shù)據(jù)集,因?yàn)?AOF 文件保存的數(shù)據(jù)集通常比 RDB 文件所保存的數(shù)據(jù)集更完整。你甚至可以關(guān)閉持久化功能,讓數(shù)據(jù)只在服務(wù)器運(yùn)行時(shí)存。

面試官:那你再說下 RDB 是怎么工作的? 我:默認(rèn) Redis 是會(huì)以快照"RDB"的形式將數(shù)據(jù)持久化到磁盤的一個(gè)二進(jìn)制文件 dump.rdb。 工作原理簡單說一下:當(dāng) Redis 需要做持久化時(shí),Redis 會(huì) fork 一個(gè)子進(jìn)程,子進(jìn)程將數(shù)據(jù)寫到磁盤上一個(gè)臨時(shí) RDB 文件中。

當(dāng)子進(jìn)程完成寫臨時(shí)文件后,將原來的 RDB 替換掉,這樣的好處是可以 copy-on-write。

我:RDB 的優(yōu)點(diǎn)是:這種文件非常適合用于備份:比如,你可以在最近的 24 小時(shí)內(nèi),每小時(shí)備份一次,并且在每個(gè)月的每一天也備份一個(gè) RDB 文件。

這樣的話,即使遇上問題,也可以隨時(shí)將數(shù)據(jù)集還原到不同的版本。RDB 非常適合災(zāi)難恢復(fù)。

RDB 的缺點(diǎn)是:如果你需要盡量避免在服務(wù)器故障時(shí)丟失數(shù)據(jù),那么RDB不合適你。

面試官:那你要不再說下 AOF?

我:(說就一起說下吧)使用 AOF 做持久化,每一個(gè)寫命令都通過 write 函數(shù)追加到 appendonly.aof 中,配置方式如下:

appendfsyncyes appendfsyncalways#每次有數(shù)據(jù)修改發(fā)生時(shí)都會(huì)寫入AOF文件。 appendfsynceverysec#每秒鐘同步一次,該策略為AOF的缺省策略。

AOF 可以做到全程持久化,只需要在配置中開啟 appendonly yes。這樣 Redis 每執(zhí)行一個(gè)修改數(shù)據(jù)的命令,都會(huì)把它添加到 AOF 文件中,當(dāng) Redis 重啟時(shí),將會(huì)讀取 AOF 文件進(jìn)行重放,恢復(fù)到 Redis 關(guān)閉前的最后時(shí)刻。

我頓了一下,繼續(xù)說:使用 AOF 的優(yōu)點(diǎn)是會(huì)讓 Redis 變得非常耐久。可以設(shè)置不同的 Fsync 策略,AOF的默認(rèn)策略是每秒鐘 Fsync 一次,在這種配置下,就算發(fā)生故障停機(jī),也最多丟失一秒鐘的數(shù)據(jù)。

缺點(diǎn)是對于相同的數(shù)據(jù)集來說,AOF 的文件體積通常要大于 RDB 文件的體積。根據(jù)所使用的 Fsync 策略,AOF 的速度可能會(huì)慢于 RDB。

面試官又問:你說了這么多,那我該用哪一個(gè)呢?

我:如果你非常關(guān)心你的數(shù)據(jù),但仍然可以承受數(shù)分鐘內(nèi)的數(shù)據(jù)丟失,那么可以額只使用 RDB 持久。

AOF 將 Redis 執(zhí)行的每一條命令追加到磁盤中,處理巨大的寫入會(huì)降低Redis的性能,不知道你是否可以接受。

數(shù)據(jù)庫備份和災(zāi)難恢復(fù):定時(shí)生成 RDB 快照非常便于進(jìn)行數(shù)據(jù)庫備份,并且 RDB 恢復(fù)數(shù)據(jù)集的速度也要比 AOF 恢復(fù)的速度快。

當(dāng)然了,Redis 支持同時(shí)開啟 RDB 和 AOF,系統(tǒng)重啟后,Redis 會(huì)優(yōu)先使用 AOF 來恢復(fù)數(shù)據(jù),這樣丟失的數(shù)據(jù)會(huì)最少。

主從復(fù)制

面試官:Redis 單節(jié)點(diǎn)存在單點(diǎn)故障問題,為了解決單點(diǎn)問題,一般都需要對 Redis 配置從節(jié)點(diǎn),然后使用哨兵來監(jiān)聽主節(jié)點(diǎn)的存活狀態(tài),如果主節(jié)點(diǎn)掛掉,從節(jié)點(diǎn)能繼續(xù)提供緩存功能,你能說說 Redis 主從復(fù)制的過程和原理嗎? 我有點(diǎn)懵,這個(gè)說來就話長了。但幸好提前準(zhǔn)備了:主從配置結(jié)合哨兵模式能解決單點(diǎn)故障問題,提高 Redis 可用性。

從節(jié)點(diǎn)僅提供讀操作,主節(jié)點(diǎn)提供寫操作。對于讀多寫少的狀況,可給主節(jié)點(diǎn)配置多個(gè)從節(jié)點(diǎn),從而提高響應(yīng)效率。

我頓了一下,接著說:關(guān)于復(fù)制過程,是這樣的:

從節(jié)點(diǎn)執(zhí)行 slaveof[masterIP][masterPort],保存主節(jié)點(diǎn)信息。

從節(jié)點(diǎn)中的定時(shí)任務(wù)發(fā)現(xiàn)主節(jié)點(diǎn)信息,建立和主節(jié)點(diǎn)的 Socket 連接。

從節(jié)點(diǎn)發(fā)送 Ping 信號,主節(jié)點(diǎn)返回 Pong,兩邊能互相通信。

連接建立后,主節(jié)點(diǎn)將所有數(shù)據(jù)發(fā)送給從節(jié)點(diǎn)(數(shù)據(jù)同步)。

主節(jié)點(diǎn)把當(dāng)前的數(shù)據(jù)同步給從節(jié)點(diǎn)后,便完成了復(fù)制的建立過程。接下來,主節(jié)點(diǎn)就會(huì)持續(xù)的把寫命令發(fā)送給從節(jié)點(diǎn),保證主從數(shù)據(jù)一致性。

面試官:那你能詳細(xì)說下數(shù)據(jù)同步的過程嗎?

(我心想:這也問的太細(xì)了吧)我:可以。Redis 2.8 之前使用 sync[runId][offset] 同步命令,Redis 2.8 之后使用 psync[runId][offset] 命令。

兩者不同在于,Sync 命令僅支持全量復(fù)制過程,Psync 支持全量和部分復(fù)制。

介紹同步之前,先介紹幾個(gè)概念:

runId:每個(gè) Redis 節(jié)點(diǎn)啟動(dòng)都會(huì)生成唯一的 uuid,每次 Redis 重啟后,runId 都會(huì)發(fā)生變化。

offset:主節(jié)點(diǎn)和從節(jié)點(diǎn)都各自維護(hù)自己的主從復(fù)制偏移量 offset,當(dāng)主節(jié)點(diǎn)有寫入命令時(shí),offset=offset+命令的字節(jié)長度。

從節(jié)點(diǎn)在收到主節(jié)點(diǎn)發(fā)送的命令后,也會(huì)增加自己的 offset,并把自己的 offset 發(fā)送給主節(jié)點(diǎn)。

這樣,主節(jié)點(diǎn)同時(shí)保存自己的 offset 和從節(jié)點(diǎn)的 offset,通過對比 offset 來判斷主從節(jié)點(diǎn)數(shù)據(jù)是否一致。

repl_backlog_size:保存在主節(jié)點(diǎn)上的一個(gè)固定長度的先進(jìn)先出隊(duì)列,默認(rèn)大小是 1MB。

主節(jié)點(diǎn)發(fā)送數(shù)據(jù)給從節(jié)點(diǎn)過程中,主節(jié)點(diǎn)還會(huì)進(jìn)行一些寫操作,這時(shí)候的數(shù)據(jù)存儲在復(fù)制緩沖區(qū)中。

從節(jié)點(diǎn)同步主節(jié)點(diǎn)數(shù)據(jù)完成后,主節(jié)點(diǎn)將緩沖區(qū)的數(shù)據(jù)繼續(xù)發(fā)送給從節(jié)點(diǎn),用于部分復(fù)制。

主節(jié)點(diǎn)響應(yīng)寫命令時(shí),不但會(huì)把命名發(fā)送給從節(jié)點(diǎn),還會(huì)寫入復(fù)制積壓緩沖區(qū),用于復(fù)制命令丟失的數(shù)據(jù)補(bǔ)救。

7355278e-584b-11eb-8b86-12bb97331649.jpg

上面是 Psync 的執(zhí)行流程,從節(jié)點(diǎn)發(fā)送 psync[runId][offset] 命令,主節(jié)點(diǎn)有三種響應(yīng):

FULLRESYNC:第一次連接,進(jìn)行全量復(fù)制

CONTINUE:進(jìn)行部分復(fù)制

ERR:不支持 psync 命令,進(jìn)行全量復(fù)制

面試官:很好,那你能具體說下全量復(fù)制和部分復(fù)制的過程嗎?

我:可以!

73677844-584b-11eb-8b86-12bb97331649.jpg

上面是全量復(fù)制的流程。主要有以下幾步:

從節(jié)點(diǎn)發(fā)送 psync ? -1 命令(因?yàn)榈谝淮伟l(fā)送,不知道主節(jié)點(diǎn)的 runId,所以為?,因?yàn)槭堑谝淮螐?fù)制,所以 offset=-1)。

主節(jié)點(diǎn)發(fā)現(xiàn)從節(jié)點(diǎn)是第一次復(fù)制,返回 FULLRESYNC {runId} {offset},runId 是主節(jié)點(diǎn)的 runId,offset 是主節(jié)點(diǎn)目前的 offset。

從節(jié)點(diǎn)接收主節(jié)點(diǎn)信息后,保存到 info 中。

主節(jié)點(diǎn)在發(fā)送 FULLRESYNC 后,啟動(dòng) bgsave 命令,生成 RDB 文件(數(shù)據(jù)持久化)。

主節(jié)點(diǎn)發(fā)送 RDB 文件給從節(jié)點(diǎn)。到從節(jié)點(diǎn)加載數(shù)據(jù)完成這段期間主節(jié)點(diǎn)的寫命令放入緩沖區(qū)。

從節(jié)點(diǎn)清理自己的數(shù)據(jù)庫數(shù)據(jù)。

從節(jié)點(diǎn)加載 RDB 文件,將數(shù)據(jù)保存到自己的數(shù)據(jù)庫中。如果從節(jié)點(diǎn)開啟了 AOF,從節(jié)點(diǎn)會(huì)異步重寫 AOF 文件。

關(guān)于部分復(fù)制有以下幾點(diǎn)說明:

①部分復(fù)制主要是 Redis 針對全量復(fù)制的過高開銷做出的一種優(yōu)化措施,使用 psync[runId][offset] 命令實(shí)現(xiàn)。

當(dāng)從節(jié)點(diǎn)正在復(fù)制主節(jié)點(diǎn)時(shí),如果出現(xiàn)網(wǎng)絡(luò)閃斷或者命令丟失等異常情況時(shí),從節(jié)點(diǎn)會(huì)向主節(jié)點(diǎn)要求補(bǔ)發(fā)丟失的命令數(shù)據(jù),主節(jié)點(diǎn)的復(fù)制積壓緩沖區(qū)將這部分?jǐn)?shù)據(jù)直接發(fā)送給從節(jié)點(diǎn)。

這樣就可以保持主從節(jié)點(diǎn)復(fù)制的一致性。補(bǔ)發(fā)的這部分?jǐn)?shù)據(jù)一般遠(yuǎn)遠(yuǎn)小于全量數(shù)據(jù)。

②主從連接中斷期間主節(jié)點(diǎn)依然響應(yīng)命令,但因復(fù)制連接中斷命令無法發(fā)送給從節(jié)點(diǎn),不過主節(jié)點(diǎn)內(nèi)的復(fù)制積壓緩沖區(qū)依然可以保存最近一段時(shí)間的寫命令數(shù)據(jù)。

③當(dāng)主從連接恢復(fù)后,由于從節(jié)點(diǎn)之前保存了自身已復(fù)制的偏移量和主節(jié)點(diǎn)的運(yùn)行 ID。因此會(huì)把它們當(dāng)做 psync 參數(shù)發(fā)送給主節(jié)點(diǎn),要求進(jìn)行部分復(fù)制。 ④主節(jié)點(diǎn)接收到 psync 命令后首先核對參數(shù) runId 是否與自身一致,如果一致,說明之前復(fù)制的是當(dāng)前主節(jié)點(diǎn)。

之后根據(jù)參數(shù) offset 在復(fù)制積壓緩沖區(qū)中查找,如果 offset 之后的數(shù)據(jù)存在,則對從節(jié)點(diǎn)發(fā)送+COUTINUE 命令,表示可以進(jìn)行部分復(fù)制。因?yàn)榫彌_區(qū)大小固定,若發(fā)生緩沖溢出,則進(jìn)行全量復(fù)制。

⑤主節(jié)點(diǎn)根據(jù)偏移量把復(fù)制積壓緩沖區(qū)里的數(shù)據(jù)發(fā)送給從節(jié)點(diǎn),保證主從復(fù)制進(jìn)入正常狀態(tài)。

哨兵

面試官:那主從復(fù)制會(huì)存在哪些問題呢?

我:主從復(fù)制會(huì)存在以下問題:

一旦主節(jié)點(diǎn)宕機(jī),從節(jié)點(diǎn)晉升為主節(jié)點(diǎn),同時(shí)需要修改應(yīng)用方的主節(jié)點(diǎn)地址,還需要命令所有從節(jié)點(diǎn)去復(fù)制新的主節(jié)點(diǎn),整個(gè)過程需要人工干預(yù)。

主節(jié)點(diǎn)的寫能力受到單機(jī)的限制。

主節(jié)點(diǎn)的存儲能力受到單機(jī)的限制。

原生復(fù)制的弊端在早期的版本中也會(huì)比較突出,比如:Redis 復(fù)制中斷后,從節(jié)點(diǎn)會(huì)發(fā)起 psync。

此時(shí)如果同步不成功,則會(huì)進(jìn)行全量同步,主庫執(zhí)行全量備份的同時(shí),可能會(huì)造成毫秒或秒級的卡頓。

面試官:那比較主流的解決方案是什么呢?

我:當(dāng)然是哨兵啊。

面試官:那么問題又來了。那你說下哨兵有哪些功能?

73a26170-584b-11eb-8b86-12bb97331649.jpg

我:如圖,是 Redis Sentinel(哨兵)的架構(gòu)圖。Redis Sentinel(哨兵)主要功能包括主節(jié)點(diǎn)存活檢測、主從運(yùn)行情況檢測、自動(dòng)故障轉(zhuǎn)移、主從切換。

Redis Sentinel 最小配置是一主一從。Redis 的 Sentinel 系統(tǒng)可以用來管理多個(gè) Redis 服務(wù)器。

該系統(tǒng)可以執(zhí)行以下四個(gè)任務(wù):

監(jiān)控:不斷檢查主服務(wù)器和從服務(wù)器是否正常運(yùn)行。

通知:當(dāng)被監(jiān)控的某個(gè) Redis 服務(wù)器出現(xiàn)問題,Sentinel 通過 API 腳本向管理員或者其他應(yīng)用程序發(fā)出通知。

自動(dòng)故障轉(zhuǎn)移:當(dāng)主節(jié)點(diǎn)不能正常工作時(shí),Sentinel 會(huì)開始一次自動(dòng)的故障轉(zhuǎn)移操作,它會(huì)將與失效主節(jié)點(diǎn)是主從關(guān)系的其中一個(gè)從節(jié)點(diǎn)升級為新的主節(jié)點(diǎn),并且將其他的從節(jié)點(diǎn)指向新的主節(jié)點(diǎn),這樣人工干預(yù)就可以免了。

配置提供者:在 Redis Sentinel 模式下,客戶端應(yīng)用在初始化時(shí)連接的是 Sentinel 節(jié)點(diǎn)集合,從中獲取主節(jié)點(diǎn)的信息。

面試官:那你能說下哨兵的工作原理嗎?

我:話不多說,直接上圖:

73f86872-584b-11eb-8b86-12bb97331649.jpg

①每個(gè) Sentinel 節(jié)點(diǎn)都需要定期執(zhí)行以下任務(wù):每個(gè) Sentinel 以每秒一次的頻率,向它所知的主服務(wù)器、從服務(wù)器以及其他的 Sentinel 實(shí)例發(fā)送一個(gè) PING 命令。(如上圖)

74180ab0-584b-11eb-8b86-12bb97331649.jpg

②如果一個(gè)實(shí)例距離最后一次有效回復(fù) PING 命令的時(shí)間超過 down-after-milliseconds 所指定的值,那么這個(gè)實(shí)例會(huì)被 Sentinel 標(biāo)記為主觀下線。(如上圖)

744f7bbc-584b-11eb-8b86-12bb97331649.jpg

③如果一個(gè)主服務(wù)器被標(biāo)記為主觀下線,那么正在監(jiān)視這個(gè)服務(wù)器的所有 Sentinel 節(jié)點(diǎn),要以每秒一次的頻率確認(rèn)主服務(wù)器的確進(jìn)入了主觀下線狀態(tài)。

746bcc90-584b-11eb-8b86-12bb97331649.jpg

④如果一個(gè)主服務(wù)器被標(biāo)記為主觀下線,并且有足夠數(shù)量的 Sentinel(至少要達(dá)到配置文件指定的數(shù)量)在指定的時(shí)間范圍內(nèi)同意這一判斷,那么這個(gè)主服務(wù)器被標(biāo)記為客觀下線。

74903ac6-584b-11eb-8b86-12bb97331649.jpg

⑤一般情況下,每個(gè) Sentinel 會(huì)以每 10 秒一次的頻率向它已知的所有主服務(wù)器和從服務(wù)器發(fā)送 INFO 命令。

當(dāng)一個(gè)主服務(wù)器被標(biāo)記為客觀下線時(shí),Sentinel 向下線主服務(wù)器的所有從服務(wù)器發(fā)送 INFO 命令的頻率,會(huì)從 10 秒一次改為每秒一次。

74bb664c-584b-11eb-8b86-12bb97331649.jpg

⑥Sentinel 和其他 Sentinel 協(xié)商客觀下線的主節(jié)點(diǎn)的狀態(tài),如果處于 SDOWN 狀態(tài),則投票自動(dòng)選出新的主節(jié)點(diǎn),將剩余從節(jié)點(diǎn)指向新的主節(jié)點(diǎn)進(jìn)行數(shù)據(jù)復(fù)制。

74d6b4d8-584b-11eb-8b86-12bb97331649.jpg

⑦當(dāng)沒有足夠數(shù)量的 Sentinel 同意主服務(wù)器下線時(shí),主服務(wù)器的客觀下線狀態(tài)就會(huì)被移除。

當(dāng)主服務(wù)器重新向 Sentinel 的 PING 命令返回有效回復(fù)時(shí),主服務(wù)器的主觀下線狀態(tài)就會(huì)被移除。

面試官:不錯(cuò),面試前沒少下工夫啊,今天 Redis 這關(guān)你過了,明天找個(gè)時(shí)間我們再聊聊其他的。(露出欣慰的微笑)

我:沒問題。

總結(jié)

本文在一次面試的過程中講述了 Redis 是什么,Redis 的特點(diǎn)和功能,Redis 緩存的使用,Redis 為什么能這么快,Redis 緩存的淘汰策略,持久化的兩種方式,Redis 高可用部分的主從復(fù)制和哨兵的基本原理。

只要功夫深,鐵杵磨成針,平時(shí)準(zhǔn)備好,面試不用慌。雖然面試不一定是這樣問的,但萬變不離其“宗”。

責(zé)任編輯:lq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)庫
    +關(guān)注

    關(guān)注

    7

    文章

    3851

    瀏覽量

    64697
  • 數(shù)據(jù)類型
    +關(guān)注

    關(guān)注

    0

    文章

    236

    瀏覽量

    13665
  • Redis
    +關(guān)注

    關(guān)注

    0

    文章

    378

    瀏覽量

    10949

原文標(biāo)題:2W 字圖解 Redis,掃盲必備!

文章出處:【微信號:DBDevs,微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    華為云 Flexus X 加速 Redis 案例實(shí)踐與詳解

    Redis 加速鏡像,更是為開發(fā)者提供了極大的便利。本文將詳細(xì)介紹如何利用華為云 Flexus X 實(shí)例自帶的 Redis 鏡像,快速部署并配置 Redis,以及通過實(shí)際案例展示其便捷性和高效性。 一、華為云 Flexus
    的頭像 發(fā)表于 01-23 17:52 ?80次閱讀
    華為云 Flexus X 加速 <b class='flag-5'>Redis</b> 案例實(shí)踐與詳解

    Redis Cluster之故障轉(zhuǎn)移

    1. Redis Cluster 簡介 Redis Cluster 是 Redis 官方提供的 Redis 集群功能。 為什么要實(shí)現(xiàn) Redis
    的頭像 發(fā)表于 01-20 09:21 ?211次閱讀
    <b class='flag-5'>Redis</b> Cluster之故障轉(zhuǎn)移

    華為云Flexus X實(shí)例,Redis性能加速評測及對比

    隨著云計(jì)算技術(shù)的飛速發(fā)展,Redis 作為一種高性能的內(nèi)存數(shù)據(jù)庫,在各種應(yīng)用場景中發(fā)揮著越來越重要的作用。為了滿足不同用戶對 Redis 性能的高要求,華為云推出了 Flexus X 實(shí)例,并提供了
    的頭像 發(fā)表于 12-29 15:47 ?215次閱讀
    華為云Flexus X實(shí)例,<b class='flag-5'>Redis</b>性能加速評測及對比

    Redis緩存與Memcached的比較

    Redis和Memcached都是廣泛使用的內(nèi)存數(shù)據(jù)存儲系統(tǒng),它們主要用于提高應(yīng)用程序的性能,通過減少對數(shù)據(jù)庫的直接訪問來加速數(shù)據(jù)檢索。以下是對Redis和Memcached的比較,涵蓋了它們的一些
    的頭像 發(fā)表于 12-18 09:33 ?246次閱讀

    Redis 開源協(xié)議調(diào)整,我們怎么辦?

    2 024 年 3 月 20 日, Redis 官方宣布,從 Redis 7.4 版本開始,Redis 將獲得源可用許可證 ( RSALv2 ) 和服務(wù)器端公共許可證 ( SSPLv1 ) 的雙重
    的頭像 發(fā)表于 05-09 22:59 ?476次閱讀
    <b class='flag-5'>Redis</b> 開源協(xié)議調(diào)整,我們怎么辦?

    Redis 開源社區(qū)持續(xù)壯大,華為云為 Valkey 項(xiàng)目注入新的活力

    華為云云原生中間件產(chǎn)品團(tuán)隊(duì)在過去的幾年里,通過向 Redis 開源社區(qū)提交代碼優(yōu)化、性能改進(jìn)和安全性增強(qiáng)的建議,以及積極參與社區(qū)討論和貢獻(xiàn)文檔,為 Redis 的發(fā)展做出了積極的貢獻(xiàn)。作為
    的頭像 發(fā)表于 05-09 22:59 ?795次閱讀
    <b class='flag-5'>Redis</b> 開源社區(qū)持續(xù)壯大,華為云為 Valkey 項(xiàng)目注入新的活力

    Redis為什么這么快?

    Redis 是基于內(nèi)存的數(shù)據(jù)庫,那不可避免的就要與磁盤數(shù)據(jù)庫做對比。對于磁盤數(shù)據(jù)庫來說,是需要將數(shù)據(jù)讀取到內(nèi)存里的,這個(gè)過程會(huì)受到磁盤 I/O 的限制。而對于內(nèi)存數(shù)據(jù)庫來說,本身數(shù)據(jù)就存在于內(nèi)存里,也就沒有了這方面的開銷。
    發(fā)表于 04-12 10:32 ?242次閱讀
    <b class='flag-5'>Redis</b>為什么這么快?

    Redis開源版與Redis企業(yè)版,怎么選用?

    點(diǎn)擊“藍(lán)字”關(guān)注我們數(shù)以千計(jì)的企業(yè)和數(shù)以百萬計(jì)的開發(fā)人員Redis開源版來構(gòu)建應(yīng)用程序。但隨著用戶數(shù)量、數(shù)據(jù)量和地區(qū)性的增加,成本、可擴(kuò)展性、運(yùn)營和可用性等問題也隨之而來。Redis企業(yè)版
    的頭像 發(fā)表于 04-04 08:04 ?1193次閱讀
    <b class='flag-5'>Redis</b>開源版與<b class='flag-5'>Redis</b>企業(yè)版,怎么選用?

    數(shù)據(jù)安全沒保障?GaussDB(for Redis) 為你保駕護(hù)航

    近日,一些用戶反饋,使用的開源 Redis 中新增了幾個(gè)未知來源的 Key。通過分析發(fā)現(xiàn),用戶使用的開源 Redis 沒有設(shè)置密碼,很可能是遭到了 Redis 擴(kuò)散病毒的攻擊,表面上只是新增了幾個(gè)
    的頭像 發(fā)表于 03-28 22:09 ?719次閱讀
    數(shù)據(jù)安全沒保障?GaussDB(for <b class='flag-5'>Redis</b>) 為你保駕護(hù)航

    GaussDB(for Redis) 特性揭秘:多租戶管理

    華為云 GaussDB(for Redis)持續(xù)完善企業(yè)級增強(qiáng)特性,是名副其實(shí)的 "Redis Plus" ,其中很經(jīng)典的企業(yè)級特性是 多租戶能力 ,支持添加只讀賬號、讀寫賬號,且具備強(qiáng)大的 DB
    的頭像 發(fā)表于 03-28 22:06 ?793次閱讀
    GaussDB(for <b class='flag-5'>Redis</b>) 特性揭秘:多租戶管理

    GaussDB(for Redis) 特性揭秘:大 key 治理

    ? 從 DBA 的視角看,大 Key 無疑是引起 Redis 線上問題的常見原因。為了解決大 Key 隱患,業(yè)務(wù)首先要遵守合理的開發(fā)規(guī)范,減少大 Key 的產(chǎn)生和訪問依賴。但有時(shí)大 Key 是在程序
    的頭像 發(fā)表于 03-28 22:06 ?713次閱讀
    GaussDB(for <b class='flag-5'>Redis</b>) 特性揭秘:大 key 治理

    GaussDB(for Redis) 游戲?qū)嵺`:玩家下線行為上報(bào)

    為保護(hù)未成年人的身心健康,2007 年國家推出網(wǎng)絡(luò)游戲防沉迷系統(tǒng),對未成年人的游戲時(shí)間進(jìn)行限制,游戲廠家需要及時(shí)感知用戶的下線時(shí)間并上報(bào)。Redis 是游戲數(shù)據(jù)庫重要選型之一,在基于開源 Redis
    的頭像 發(fā)表于 03-28 22:03 ?567次閱讀

    新版 Redis 不再“開源”,對使用者都有哪些影響?

    2024 年 3 月 20 日,Redis Labs 宣布從 Redis 7.4 開始,將原先比較寬松的 BSD 源碼使用協(xié)議修改為 RSAv2和 SSPLv1協(xié)議。該變化意味著 Redis
    的頭像 發(fā)表于 03-27 22:30 ?558次閱讀
    新版 <b class='flag-5'>Redis</b> 不再“開源”,對使用者都有哪些影響?

    Redis實(shí)現(xiàn)分布式多規(guī)則限流的方式介紹

    市面上很多介紹 Redis 如何實(shí)現(xiàn)限流的,但是大部分都有一個(gè)缺點(diǎn),就是只能實(shí)現(xiàn)單一的限流,比如 1 分鐘訪問 1 次或者 60 分鐘訪問 10 次這種,但是如果想一個(gè)接口兩種規(guī)則都需要滿足呢,我們的項(xiàng)目又是分布式項(xiàng)目,應(yīng)該如何解決,下面就介紹一下 Redis 實(shí)現(xiàn)分布式
    的頭像 發(fā)表于 02-26 10:07 ?566次閱讀
    <b class='flag-5'>Redis</b>實(shí)現(xiàn)分布式多規(guī)則限流的方式介紹

    Redis官方搜索引擎來了,性能炸裂!

    RediSearch 是一個(gè) Redis 模塊,為 Redis 提供查詢、二級索引和全文搜索功能。
    的頭像 發(fā)表于 02-21 10:01 ?2553次閱讀
    <b class='flag-5'>Redis</b>官方搜索引擎來了,性能炸裂!
    主站蜘蛛池模板: 91大神精品全国在线观看 | 中文字幕在线播放第一页 | 亚洲午夜影视 | 四虎在线永久视频观看 | 视频免费观看视频 | 午夜影院黄色片 | 4虎影视国产在线观看精品 4虎影院永久地址www | 777午夜精品免费播放 | 国产成人综合一区人人 | 天堂在线www天堂中文在线 | 3p高h文| 国产精品久久久久久久久免费hd | 久久精品亚瑟全部免费观看 | 特黄视频 | 亚洲欧美4444kkkk | 国产成人精品日本亚洲网站 | 在线色色视频 | 日本黄黄 | 日韩有码电影 | 中文天堂最新版资源新版天堂资源 | 国产精品欧美久久久久天天影视 | 欧美爆操 | 曰本性l交片视频视频 | 欧美性猛交xxxx | 四虎影视永久在线精品免费播放 | 欧美黑人三级 | 黄色免费网站在线播放 | 91三级在线| 欧美成人观看免费全部完小说 | 小泽玛利亚厕所大喷水 | 亚洲综合五月天婷 | 激情五月婷婷色 | 国产手机在线看片 | 亚洲天堂视频一区 | 久久在精品线影院精品国产 | 狠狠色丁香久久综合网 | 老师下面好紧 | 欧美不卡一区 | 久久天天躁夜夜躁狠狠85麻豆 | 亚洲三级色| 免费观看交性大片 |