1.空间索引 - GeoHash算法及其实现优化
2.RedisåMemcachedçåºå«
3.基于Redis实现点赞及排行榜功能
空间索引 - GeoHash算法及其实现优化
空间索引 - GeoHash算法及其实现优化
在深入理解空间索引的码实用途和数据库支持后,我们转向探讨GeoHash算法,码实一种在B树基础上利用网格索引思想的码实空间索引实现方式。 GeoHash的码实基本原理是通过墨卡托投影将地球表面划分为小方格,相同的码实前缀表示附近的点。简单地说,码实测距源码GeoHash是码实通过标记每个方格并利用B树索引找到具有相同前缀的点。 墨卡托投影虽有误差,码实但主要用于简化处理,码实将地球表面视为正方形。码实在实践中,码实GeoHash遇到边界点问题,码实需要扩展查询范围。码实通过增加相邻方格的码实考虑,我们通过二进制码加一来确定周边方格的码实前缀。 在实现层面,Redis的金十五公式源码GEO函数处理查询范围与GeoHash码位数之间的映射,通过将二进制码转换为double类型的score存储在sorted set中,实现了接近最优的查询效率。通过PHP实现的GeoHash算法,我们能够解决精度和索引长度之间的平衡问题。 总结起来,GeoHash算法是一个复杂的过程,涉及到地图划分、精度控制和边界处理。云海计费5.1源码虽然存在更高效率的四叉树和R树,但GeoHash的优化方法提供了有价值的参考。如果你对这个主题感兴趣,可以访问我的GitHub源码和相关链接进行深入学习。RedisåMemcachedçåºå«
Redisçä½è Salvatore Sanfilippoæ¾ç»å¯¹è¿ä¸¤ç§åºäºå åçæ°æ®åå¨ç³»ç»è¿è¡è¿æ¯è¾ï¼1ãRedisæ¯ææå¡å¨ç«¯çæ°æ®æä½ï¼Redisç¸æ¯Memcachedæ¥è¯´ï¼æ¥ææ´å¤çæ°æ®ç»æå并æ¯ææ´ä¸°å¯çæ°æ®æä½ï¼é常å¨Memcachedéï¼ä½ éè¦å°æ°æ®æ¿å°å®¢æ·ç«¯æ¥è¿è¡ç±»ä¼¼çä¿®æ¹åsetåå»ãè¿å¤§å¤§å¢å äºç½ç»IOç次æ°åæ°æ®ä½ç§¯ãå¨Redisä¸ï¼è¿äºå¤æçæä½é常åä¸è¬çGET/SETä¸æ ·é«æãæ以ï¼å¦æéè¦ç¼åè½å¤æ¯ææ´å¤æçç»æåæä½ï¼é£ä¹Redisä¼æ¯ä¸éçéæ©ã
2ãå å使ç¨æç对æ¯ï¼ä½¿ç¨ç®åçkey-valueåå¨çè¯ï¼Memcachedçå åå©ç¨çæ´é«ï¼èå¦æRediséç¨hashç»ææ¥åkey-valueåå¨ï¼ç±äºå ¶ç»åå¼çå缩ï¼å ¶å åå©ç¨çä¼é«äºMemcachedã
3ãæ§è½å¯¹æ¯ï¼ç±äºRedisåªä½¿ç¨åæ ¸ï¼èMemcachedå¯ä»¥ä½¿ç¨å¤æ ¸ï¼æ以平åæ¯ä¸ä¸ªæ ¸ä¸Rediså¨åå¨å°æ°æ®æ¶æ¯Memcachedæ§è½æ´é«ãèå¨k以ä¸çæ°æ®ä¸ï¼Memcachedæ§è½è¦é«äºRedisï¼è½ç¶Redisæè¿ä¹å¨åå¨å¤§æ°æ®çæ§è½ä¸è¿è¡ä¼åï¼ä½æ¯æ¯èµ·Memcachedï¼è¿æ¯ç¨æéè²ã
å ·ä½ä¸ºä»ä¹ä¼åºç°ä¸é¢çç»è®ºï¼ä»¥ä¸ä¸ºæ¶éå°çèµæï¼
1ãæ°æ®ç±»åæ¯æä¸å
ä¸Memcachedä» æ¯æç®åçkey-valueç»æçæ°æ®è®°å½ä¸åï¼Redisæ¯æçæ°æ®ç±»åè¦ä¸°å¯å¾å¤ãæ为常ç¨çæ°æ®ç±»å主è¦ç±äºç§ï¼StringãHashãListãSetåSorted SetãRediså é¨ä½¿ç¨ä¸ä¸ªredisObject对象æ¥è¡¨ç¤ºææçkeyåvalueãredisObjectæ主è¦çä¿¡æ¯å¦å¾æ示ï¼
type代表ä¸ä¸ªvalueå¯¹è±¡å ·ä½æ¯ä½ç§æ°æ®ç±»åï¼encodingæ¯ä¸åæ°æ®ç±»åå¨rediså é¨çåå¨æ¹å¼ï¼æ¯å¦ï¼type=string代表valueåå¨çæ¯ä¸ä¸ªæ®éå符串ï¼é£ä¹å¯¹åºçencodingå¯ä»¥æ¯rawæè æ¯intï¼å¦ææ¯intå代表å®é rediså é¨æ¯ææ°å¼åç±»åå¨å表示è¿ä¸ªå符串çï¼å½ç¶åææ¯è¿ä¸ªå符串æ¬èº«å¯ä»¥ç¨æ°å¼è¡¨ç¤ºï¼æ¯å¦:ââ³ ââè¿æ ·çå符串ãåªææå¼äºRedisçèæå ååè½ï¼vmå段å段æä¼çæ£çåé å åï¼è¯¥åè½é»è®¤æ¯å ³éç¶æçã
1ï¼String
常ç¨å½ä»¤ï¼set/get/decr/incr/mgetçï¼
åºç¨åºæ¯ï¼Stringæ¯æ常ç¨çä¸ç§æ°æ®ç±»åï¼æ®éçkey/valueåå¨é½å¯ä»¥å½ä¸ºæ¤ç±»ï¼
å®ç°æ¹å¼ï¼Stringå¨rediså é¨åå¨é»è®¤å°±æ¯ä¸ä¸ªå符串ï¼è¢«redisObjectæå¼ç¨ï¼å½éå°incrãdecrçæä½æ¶ä¼è½¬ææ°å¼åè¿è¡è®¡ç®ï¼æ¤æ¶redisObjectçencodingå段为intã
2ï¼Hash
常ç¨å½ä»¤ï¼hget/hset/hgetallç
åºç¨åºæ¯ï¼æ们è¦åå¨ä¸ä¸ªç¨æ·ä¿¡æ¯å¯¹è±¡æ°æ®ï¼å ¶ä¸å æ¬ç¨æ·IDãç¨æ·å§åãå¹´é¾åçæ¥ï¼éè¿ç¨æ·IDæ们å¸æè·å该ç¨æ·çå§åæè å¹´é¾æè çæ¥ï¼
å®ç°æ¹å¼ï¼RedisçHashå®é æ¯å é¨åå¨çValue为ä¸ä¸ªHashMapï¼å¹¶æä¾äºç´æ¥ååè¿ä¸ªMapæåçæ¥å£ãå¦å¾æ示ï¼Keyæ¯ç¨æ·ID, valueæ¯ä¸ä¸ªMapãè¿ä¸ªMapçkeyæ¯æåçå±æ§åï¼valueæ¯å±æ§å¼ãè¿æ ·å¯¹æ°æ®çä¿®æ¹åååé½å¯ä»¥ç´æ¥éè¿å ¶å é¨MapçKey(Redisé称å é¨Mapçkey为field), ä¹å°±æ¯éè¿ key(ç¨æ·ID) + field(å±æ§æ ç¾) å°±å¯ä»¥æä½å¯¹åºå±æ§æ°æ®ãå½åHashMapçå®ç°æ两ç§æ¹å¼ï¼å½HashMapçæåæ¯è¾å°æ¶Redis为äºèçå åä¼éç¨ç±»ä¼¼ä¸ç»´æ°ç»çæ¹å¼æ¥ç´§ååå¨ï¼èä¸ä¼éç¨çæ£çHashMapç»æï¼è¿æ¶å¯¹åºçvalueçredisObjectçencoding为zipmapï¼å½æåæ°éå¢å¤§æ¶ä¼èªå¨è½¬æçæ£çHashMap,æ¤æ¶encoding为htã
请ç¹å»è¾å ¥å¾çæè¿°
3ï¼List
常ç¨å½ä»¤ï¼lpush/rpush/lpop/rpop/lrangeçï¼
åºç¨åºæ¯ï¼Redis listçåºç¨åºæ¯é常å¤ï¼ä¹æ¯Redisæéè¦çæ°æ®ç»æä¹ä¸ï¼æ¯å¦twitterçå ³æ³¨å表ï¼ç²ä¸å表çé½å¯ä»¥ç¨Redisçlistç»ææ¥å®ç°ï¼
å®ç°æ¹å¼ï¼Redis listçå®ç°ä¸ºä¸ä¸ªååé¾è¡¨ï¼å³å¯ä»¥æ¯æååæ¥æ¾åéåï¼æ´æ¹ä¾¿æä½ï¼ä¸è¿å¸¦æ¥äºé¨åé¢å¤çå åå¼éï¼Rediså é¨çå¾å¤å®ç°ï¼å æ¬åéç¼å²éåçä¹é½æ¯ç¨çè¿ä¸ªæ°æ®ç»æã
4ï¼Set
常ç¨å½ä»¤ï¼sadd/spop/smembers/sunionçï¼
åºç¨åºæ¯ï¼Redis set对å¤æä¾çåè½ä¸list类似æ¯ä¸ä¸ªå表çåè½ï¼ç¹æ®ä¹å¤å¨äºsetæ¯å¯ä»¥èªå¨æéçï¼å½ä½ éè¦åå¨ä¸ä¸ªå表æ°æ®ï¼åä¸å¸æåºç°éå¤æ°æ®æ¶ï¼setæ¯ä¸ä¸ªå¾å¥½çéæ©ï¼å¹¶ä¸setæä¾äºå¤ææ个æåæ¯å¦å¨ä¸ä¸ªsetéåå çéè¦æ¥å£ï¼è¿ä¸ªä¹æ¯listæä¸è½æä¾çï¼
å®ç°æ¹å¼ï¼set çå é¨å®ç°æ¯ä¸ä¸ª valueæ°¸è¿ä¸ºnullçHashMapï¼å®é å°±æ¯éè¿è®¡ç®hashçæ¹å¼æ¥å¿«éæéçï¼è¿ä¹æ¯setè½æä¾å¤æä¸ä¸ªæåæ¯å¦å¨éåå çåå ã
5ï¼Sorted Set
常ç¨å½ä»¤ï¼zadd/zrange/zrem/zcardçï¼
åºç¨åºæ¯ï¼Redis sorted setç使ç¨åºæ¯ä¸set类似ï¼åºå«æ¯setä¸æ¯èªå¨æåºçï¼èsorted setå¯ä»¥éè¿ç¨æ·é¢å¤æä¾ä¸ä¸ªä¼å 级(score)çåæ°æ¥ä¸ºæåæåºï¼å¹¶ä¸æ¯æå ¥æåºçï¼å³èªå¨æåºãå½ä½ éè¦ä¸ä¸ªæåºç并ä¸ä¸éå¤çéåå表ï¼é£ä¹å¯ä»¥éæ©sorted setæ°æ®ç»æï¼æ¯å¦twitter çpublic timelineå¯ä»¥ä»¥å表æ¶é´ä½ä¸ºscoreæ¥åå¨ï¼è¿æ ·è·åæ¶å°±æ¯èªå¨ææ¶é´æ好åºçã
å®ç°æ¹å¼ï¼Redis sorted setçå é¨ä½¿ç¨HashMapåè·³è·è¡¨(SkipList)æ¥ä¿è¯æ°æ®çåå¨åæåºï¼HashMapéæ¾çæ¯æåå°scoreçæ å°ï¼èè·³è·è¡¨éåæ¾çæ¯ææçæåï¼æåºä¾æ®æ¯HashMapéåçscore,使ç¨è·³è·è¡¨çç»æå¯ä»¥è·å¾æ¯è¾é«çæ¥æ¾æçï¼å¹¶ä¸å¨å®ç°ä¸æ¯è¾ç®åã
2ãå å管çæºå¶ä¸å
å¨Redisä¸ï¼å¹¶ä¸æ¯ææçæ°æ®é½ä¸ç´åå¨å¨å åä¸çãè¿æ¯åMemcachedç¸æ¯ä¸ä¸ªæ大çåºå«ãå½ç©çå åç¨å®æ¶ï¼Rediså¯ä»¥å°ä¸äºå¾ä¹ 没ç¨å°çvalue交æ¢å°ç£çã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ä¸è¯»åæ°æ®çæ¶åï¼å¦æ读åçkey对åºçvalueä¸å¨å åä¸ï¼é£ä¹Rediså°±éè¦ä»swapæ件ä¸å è½½ç¸åºæ°æ®ï¼ç¶ååè¿åç»è¯·æ±æ¹ã è¿éå°±åå¨ä¸ä¸ªI/O线ç¨æ± çé®é¢ãå¨é»è®¤çæ åµä¸ï¼Redisä¼åºç°é»å¡ï¼å³å®æææçswapæ件å è½½åæä¼ç¸åºãè¿ç§çç¥å¨å®¢æ·ç«¯çæ°éè¾å°ï¼è¿è¡æ¹éæä½çæ¶åæ¯è¾åéãä½æ¯å¦æå°Redisåºç¨å¨ä¸ä¸ªå¤§åçç½ç«åºç¨ç¨åºä¸ï¼è¿æ¾ç¶æ¯æ æ³æ»¡è¶³å¤§å¹¶åçæ åµçãæ以Redisè¿è¡æ们设置I/O线ç¨æ± ç大å°ï¼å¯¹éè¦ä»swapæ件ä¸å è½½ç¸åºæ°æ®ç读å请æ±è¿è¡å¹¶åæä½ï¼åå°é»å¡çæ¶é´ã
对äºåRedisåMemcachedè¿ç§åºäºå åçæ°æ®åºç³»ç»æ¥è¯´ï¼å å管ççæçé«ä½æ¯å½±åç³»ç»æ§è½çå ³é®å ç´ ãä¼ ç»Cè¯è¨ä¸çmalloc/freeå½æ°æ¯æ常ç¨çåé åéæ¾å åçæ¹æ³ï¼ä½æ¯è¿ç§æ¹æ³åå¨çå¾å¤§ç缺é·ï¼é¦å ï¼å¯¹äºå¼å人åæ¥è¯´ä¸å¹é çmallocåfree容æé æå åæ³é²ï¼å ¶æ¬¡é¢ç¹è°ç¨ä¼é æ大éå åç¢çæ æ³åæ¶éæ°å©ç¨ï¼éä½å åå©ç¨çï¼æåä½ä¸ºç³»ç»è°ç¨ï¼å ¶ç³»ç»å¼éè¿è¿å¤§äºä¸è¬å½æ°è°ç¨ãæ以ï¼ä¸ºäºæé«å åç管çæçï¼é«æçå å管çæ¹æ¡é½ä¸ä¼ç´æ¥ä½¿ç¨malloc/freeè°ç¨ãRedisåMemcachedå使ç¨äºèªèº«è®¾è®¡çå å管çæºå¶ï¼ä½æ¯å®ç°æ¹æ³åå¨å¾å¤§çå·®å¼ï¼ä¸é¢å°ä¼å¯¹ä¸¤è çå å管çæºå¶åå«è¿è¡ä»ç»ã
Memcachedé»è®¤ä½¿ç¨Slab Allocationæºå¶ç®¡çå åï¼å ¶ä¸»è¦ææ³æ¯æç §é¢å è§å®ç大å°ï¼å°åé çå ååå²æç¹å®é¿åº¦çå以åå¨ç¸åºé¿åº¦çkey-valueæ°æ®è®°å½ï¼ä»¥å®å ¨è§£å³å åç¢çé®é¢ãSlab Allocationæºå¶åªä¸ºåå¨å¤é¨æ°æ®è设计ï¼ä¹å°±æ¯è¯´ææçkey-valueæ°æ®é½åå¨å¨Slab Allocationç³»ç»éï¼èMemcachedçå ¶å®å å请æ±åéè¿æ®éçmalloc/freeæ¥ç³è¯·ï¼å 为è¿äºè¯·æ±çæ°éåé¢çå³å®äºå®ä»¬ä¸ä¼å¯¹æ´ä¸ªç³»ç»çæ§è½é æå½±åSlab Allocationçåçç¸å½ç®åã å¦å¾æ示ï¼å®é¦å ä»æä½ç³»ç»ç³è¯·ä¸å¤§åå åï¼å¹¶å°å ¶åå²æåç§å°ºå¯¸çåChunkï¼å¹¶æ尺寸ç¸åçååæç»Slab Classãå ¶ä¸ï¼Chunkå°±æ¯ç¨æ¥åå¨key-valueæ°æ®çæå°åä½ãæ¯ä¸ªSlab Classç大å°ï¼å¯ä»¥å¨Memcachedå¯å¨çæ¶åéè¿å¶å®Growth Factoræ¥æ§å¶ãåå®å¾ä¸Growth Factorçåå¼ä¸º1.ï¼å¦æ第ä¸ç»Chunkç大å°ä¸ºä¸ªåèï¼ç¬¬äºç»Chunkç大å°å°±ä¸ºä¸ªåèï¼ä¾æ¤ç±»æ¨ã
请ç¹å»è¾å ¥å¾çæè¿°
å½Memcachedæ¥æ¶å°å®¢æ·ç«¯åéè¿æ¥çæ°æ®æ¶é¦å ä¼æ ¹æ®æ¶å°æ°æ®ç大å°éæ©ä¸ä¸ªæåéçSlab Classï¼ç¶åéè¿æ¥è¯¢Memcachedä¿åçç该Slab Classå 空é²Chunkçå表就å¯ä»¥æ¾å°ä¸ä¸ªå¯ç¨äºåå¨æ°æ®çChunkãå½ä¸æ¡æ°æ®åºè¿ææè 丢å¼æ¶ï¼è¯¥è®°å½æå ç¨çChunkå°±å¯ä»¥åæ¶ï¼éæ°æ·»å å°ç©ºé²å表ä¸ãä»ä»¥ä¸è¿ç¨æ们å¯ä»¥çåºMemcachedçå å管çå¶æçé«ï¼èä¸ä¸ä¼é æå åç¢çï¼ä½æ¯å®æ大ç缺ç¹å°±æ¯ä¼å¯¼è´ç©ºé´æµªè´¹ãå 为æ¯ä¸ªChunké½åé äºç¹å®é¿åº¦çå å空é´ï¼æ以åé¿æ°æ®æ æ³å åå©ç¨è¿äºç©ºé´ãå¦å¾ æ示ï¼å°ä¸ªåèçæ°æ®ç¼åå°ä¸ªåèçChunkä¸ï¼å©ä½ç个åè就浪费æäºã
请ç¹å»è¾å ¥å¾çæè¿°
Redisçå å管ç主è¦éè¿æºç ä¸zmalloc.håzmalloc.c两个æ件æ¥å®ç°çãRedis为äºæ¹ä¾¿å åç管çï¼å¨åé ä¸åå åä¹åï¼ä¼å°è¿åå åç大å°åå ¥å ååç头é¨ãå¦å¾æ示ï¼real_ptræ¯redisè°ç¨mallocåè¿åçæéãrediså°å ååç大å°sizeåå ¥å¤´é¨ï¼sizeæå æ®çå å大å°æ¯å·²ç¥çï¼ä¸ºsize_tç±»åçé¿åº¦ï¼ç¶åè¿året_ptrãå½éè¦éæ¾å åçæ¶åï¼ret_ptrè¢«ä¼ ç»å å管çç¨åºãéè¿ret_ptrï¼ç¨åºå¯ä»¥å¾å®¹æçç®åºreal_ptrçå¼ï¼ç¶åå°real_pträ¼ ç»freeéæ¾å åã
请ç¹å»è¾å ¥å¾çæè¿°
Rediséè¿å®ä¹ä¸ä¸ªæ°ç»æ¥è®°å½ææçå ååé æ åµï¼è¿ä¸ªæ°ç»çé¿åº¦ä¸ºZMALLOC_MAX_ALLOC_STATãæ°ç»çæ¯ä¸ä¸ªå ç´ ä»£è¡¨å½åç¨åºæåé çå ååç个æ°ï¼ä¸å ååç大å°ä¸ºè¯¥å ç´ çä¸æ ãå¨æºç ä¸ï¼è¿ä¸ªæ°ç»ä¸ºzmalloc_allocationsãzmalloc_allocations[]代表已ç»åé çé¿åº¦ä¸ºbytesçå ååç个æ°ãzmalloc.cä¸æä¸ä¸ªéæåéused_memoryç¨æ¥è®°å½å½ååé çå åæ»å¤§å°ãæ以ï¼æ»çæ¥çï¼Rediséç¨çæ¯å è£ çmallc/freeï¼ç¸è¾äºMemcachedçå å管çæ¹æ³æ¥è¯´ï¼è¦ç®åå¾å¤ã
3ãæ°æ®æä¹ åæ¯æ
Redisè½ç¶æ¯åºäºå åçåå¨ç³»ç»ï¼ä½æ¯å®æ¬èº«æ¯æ¯æå åæ°æ®çæä¹ åçï¼èä¸æä¾ä¸¤ç§ä¸»è¦çæä¹ åçç¥ï¼RDBå¿«ç §åAOFæ¥å¿ãèmemcachedæ¯ä¸æ¯ææ°æ®æä¹ åæä½çã
1ï¼RDBå¿«ç §
Redisæ¯æå°å½åæ°æ®çå¿«ç §åæä¸ä¸ªæ°æ®æ件çæä¹ åæºå¶ï¼å³RDBå¿«ç §ãä½æ¯ä¸ä¸ªæç»åå ¥çæ°æ®åºå¦ä½çæå¿«ç §å¢ï¼Redisåå©äºforkå½ä»¤çcopy on writeæºå¶ãå¨çæå¿«ç §æ¶ï¼å°å½åè¿ç¨forkåºä¸ä¸ªåè¿ç¨ï¼ç¶åå¨åè¿ç¨ä¸å¾ªç¯ææçæ°æ®ï¼å°æ°æ®åæ为RDBæ件ãæ们å¯ä»¥éè¿Redisçsaveæ令æ¥é ç½®RDBå¿«ç §çæçæ¶æºï¼æ¯å¦é ç½®åéå°±çæå¿«ç §ï¼ä¹å¯ä»¥é ç½®æ次åå ¥å°±çæå¿«ç §ï¼ä¹å¯ä»¥å¤ä¸ªè§åä¸èµ·å®æ½ãè¿äºè§åçå®ä¹å°±å¨Redisçé ç½®æ件ä¸ï¼ä½ ä¹å¯ä»¥éè¿RedisçCONFIG SETå½ä»¤å¨Redisè¿è¡æ¶è®¾ç½®è§åï¼ä¸éè¦éå¯Redisã
RedisçRDBæ件ä¸ä¼åæï¼å ä¸ºå ¶åæä½æ¯å¨ä¸ä¸ªæ°è¿ç¨ä¸è¿è¡çï¼å½çæä¸ä¸ªæ°çRDBæ件æ¶ï¼Redisçæçåè¿ç¨ä¼å å°æ°æ®åå°ä¸ä¸ªä¸´æ¶æ件ä¸ï¼ç¶åéè¿ååæ§renameç³»ç»è°ç¨å°ä¸´æ¶æ件éå½å为RDBæ件ï¼è¿æ ·å¨ä»»ä½æ¶ååºç°æ éï¼RedisçRDBæ件é½æ»æ¯å¯ç¨çãåæ¶ï¼RedisçRDBæ件ä¹æ¯Redis主ä»åæ¥å é¨å®ç°ä¸çä¸ç¯ãRDBæä»çä¸è¶³ï¼å°±æ¯ä¸æ¦æ°æ®åºåºç°é®é¢ï¼é£ä¹æ们çRDBæ件ä¸ä¿åçæ°æ®å¹¶ä¸æ¯å ¨æ°çï¼ä»ä¸æ¬¡RDBæ件çæå°Redisåæºè¿æ®µæ¶é´çæ°æ®å ¨é¨ä¸¢æäºãå¨æäºä¸å¡ä¸ï¼è¿æ¯å¯ä»¥å¿åçã
2ï¼AOFæ¥å¿
AOFæ¥å¿çå ¨ç§°æ¯append only fileï¼å®æ¯ä¸ä¸ªè¿½å åå ¥çæ¥å¿æ件ãä¸ä¸è¬æ°æ®åºçbinlogä¸åçæ¯ï¼AOFæ件æ¯å¯è¯å«ç纯ææ¬ï¼å®çå 容就æ¯ä¸ä¸ªä¸ªçRedisæ åå½ä»¤ãåªæé£äºä¼å¯¼è´æ°æ®åçä¿®æ¹çå½ä»¤æä¼è¿½å å°AOFæ件ãæ¯ä¸æ¡ä¿®æ¹æ°æ®çå½ä»¤é½çæä¸æ¡æ¥å¿ï¼AOFæ件ä¼è¶æ¥è¶å¤§ï¼æ以Redisåæä¾äºä¸ä¸ªåè½ï¼å«åAOF rewriteãå ¶åè½å°±æ¯éæ°çæä¸ä»½AOFæ件ï¼æ°çAOFæ件ä¸ä¸æ¡è®°å½çæä½åªä¼æä¸æ¬¡ï¼èä¸åä¸ä»½èæ件é£æ ·ï¼å¯è½è®°å½äºå¯¹åä¸ä¸ªå¼çå¤æ¬¡æä½ãå ¶çæè¿ç¨åRDB类似ï¼ä¹æ¯forkä¸ä¸ªè¿ç¨ï¼ç´æ¥éåæ°æ®ï¼åå ¥æ°çAOF临æ¶æ件ãå¨åå ¥æ°æ件çè¿ç¨ä¸ï¼ææçåæä½æ¥å¿è¿æ¯ä¼åå°åæ¥èçAOFæ件ä¸ï¼åæ¶è¿ä¼è®°å½å¨å åç¼å²åºä¸ãå½éå®æä½å®æåï¼ä¼å°ææç¼å²åºä¸çæ¥å¿ä¸æ¬¡æ§åå ¥å°ä¸´æ¶æ件ä¸ãç¶åè°ç¨ååæ§çrenameå½ä»¤ç¨æ°çAOFæ件å代èçAOFæ件ã
AOFæ¯ä¸ä¸ªåæ件æä½ï¼å ¶ç®çæ¯å°æä½æ¥å¿åå°ç£çä¸ï¼æ以å®ä¹åæ ·ä¼éå°æ们ä¸é¢è¯´çåæä½çæµç¨ãå¨Redisä¸å¯¹AOFè°ç¨writeåå ¥åï¼éè¿appendfsyncé项æ¥æ§å¶è°ç¨fsyncå°å ¶åå°ç£çä¸çæ¶é´ï¼ä¸é¢appendfsyncçä¸ä¸ªè®¾ç½®é¡¹ï¼å®å ¨å¼ºåº¦éæ¸å强ã
appendfsync no å½è®¾ç½®appendfsync为noçæ¶åï¼Redisä¸ä¼ä¸»å¨è°ç¨fsyncå»å°AOFæ¥å¿å 容åæ¥å°ç£çï¼æ以è¿ä¸åå°±å®å ¨ä¾èµäºæä½ç³»ç»çè°è¯äºã对大å¤æ°Linuxæä½ç³»ç»ï¼æ¯æ¯ç§è¿è¡ä¸æ¬¡fsyncï¼å°ç¼å²åºä¸çæ°æ®åå°ç£çä¸ã
appendfsync everysec å½è®¾ç½®appendfsync为everysecçæ¶åï¼Redisä¼é»è®¤æ¯éä¸ç§è¿è¡ä¸æ¬¡fsyncè°ç¨ï¼å°ç¼å²åºä¸çæ°æ®åå°ç£çãä½æ¯å½è¿ä¸æ¬¡çfsyncè°ç¨æ¶é¿è¶ è¿1ç§æ¶ãRedisä¼éå延è¿fsyncççç¥ï¼åçä¸ç§éãä¹å°±æ¯å¨ä¸¤ç§ååè¿è¡fsyncï¼è¿ä¸æ¬¡çfsyncå°±ä¸ç®¡ä¼æ§è¡å¤é¿æ¶é´é½ä¼è¿è¡ãè¿æ¶åç±äºå¨fsyncæ¶æ件æ述符ä¼è¢«é»å¡ï¼æ以å½åçåæä½å°±ä¼é»å¡ãæ以ç»è®ºå°±æ¯ï¼å¨ç»å¤§å¤æ°æ åµä¸ï¼Redisä¼æ¯éä¸ç§è¿è¡ä¸æ¬¡fsyncãå¨æåçæ åµä¸ï¼ä¸¤ç§éä¼è¿è¡ä¸æ¬¡fsyncæä½ãè¿ä¸æä½å¨å¤§å¤æ°æ°æ®åºç³»ç»ä¸è¢«ç§°ä¸ºgroup commitï¼å°±æ¯ç»åå¤æ¬¡åæä½çæ°æ®ï¼ä¸æ¬¡æ§å°æ¥å¿åå°ç£çã
appednfsync always å½è®¾ç½®appendfsync为alwaysæ¶ï¼æ¯ä¸æ¬¡åæä½é½ä¼è°ç¨ä¸æ¬¡fsyncï¼è¿æ¶æ°æ®æ¯æå®å ¨çï¼å½ç¶ï¼ç±äºæ¯æ¬¡é½ä¼æ§è¡fsyncï¼æä»¥å ¶æ§è½ä¹ä¼åå°å½±åã
对äºä¸è¬æ§çä¸å¡éæ±ï¼å»ºè®®ä½¿ç¨RDBçæ¹å¼è¿è¡æä¹ åï¼åå æ¯RDBçå¼é并ç¸æ¯AOFæ¥å¿è¦ä½å¾å¤ï¼å¯¹äºé£äºæ æ³å¿æ°æ®ä¸¢å¤±çåºç¨ï¼å»ºè®®ä½¿ç¨AOFæ¥å¿ã
4ãé群管ççä¸å
Memcachedæ¯å ¨å åçæ°æ®ç¼å²ç³»ç»ï¼Redisè½ç¶æ¯ææ°æ®çæä¹ åï¼ä½æ¯å ¨å åæ¯ç«ææ¯å ¶é«æ§è½çæ¬è´¨ãä½ä¸ºåºäºå åçåå¨ç³»ç»æ¥è¯´ï¼æºå¨ç©çå åç大å°å°±æ¯ç³»ç»è½å¤å®¹çº³çæ大æ°æ®éãå¦æéè¦å¤ççæ°æ®éè¶ è¿äºåå°æºå¨çç©çå å大å°ï¼å°±éè¦æ建åå¸å¼é群æ¥æ©å±åå¨è½åã
Memcachedæ¬èº«å¹¶ä¸æ¯æåå¸å¼ï¼å æ¤åªè½å¨å®¢æ·ç«¯éè¿åä¸è´æ§åå¸è¿æ ·çåå¸å¼ç®æ³æ¥å®ç°Memcachedçåå¸å¼åå¨ãä¸å¾ç»åºäºMemcachedçåå¸å¼åå¨å®ç°æ¶æãå½å®¢æ·ç«¯åMemcachedé群åéæ°æ®ä¹åï¼é¦å ä¼éè¿å ç½®çåå¸å¼ç®æ³è®¡ç®åºè¯¥æ¡æ°æ®çç®æ èç¹ï¼ç¶åæ°æ®ä¼ç´æ¥åéå°è¯¥èç¹ä¸åå¨ãä½å®¢æ·ç«¯æ¥è¯¢æ°æ®æ¶ï¼åæ ·è¦è®¡ç®åºæ¥è¯¢æ°æ®æå¨çèç¹ï¼ç¶åç´æ¥å该èç¹åéæ¥è¯¢è¯·æ±ä»¥è·åæ°æ®ã
请ç¹å»è¾å ¥å¾çæè¿°
ç¸è¾äºMemcachedåªè½éç¨å®¢æ·ç«¯å®ç°åå¸å¼åå¨ï¼Redisæ´ååäºå¨æå¡å¨ç«¯æ建åå¸å¼åå¨ãææ°çæ¬çRediså·²ç»æ¯æäºåå¸å¼åå¨åè½ãRedis Clusteræ¯ä¸ä¸ªå®ç°äºåå¸å¼ä¸å 许åç¹æ éçRedisé«çº§çæ¬ï¼å®æ²¡æä¸å¿èç¹ï¼å ·æ线æ§å¯ä¼¸ç¼©çåè½ãä¸å¾ç»åºRedis Clusterçåå¸å¼åå¨æ¶æï¼å ¶ä¸èç¹ä¸èç¹ä¹é´éè¿äºè¿å¶åè®®è¿è¡éä¿¡ï¼èç¹ä¸å®¢æ·ç«¯ä¹é´éè¿asciiåè®®è¿è¡éä¿¡ãå¨æ°æ®çæ¾ç½®çç¥ä¸ï¼Redis Clusterå°æ´ä¸ªkeyçæ°å¼ååæ个åå¸æ§½ï¼æ¯ä¸ªèç¹ä¸å¯ä»¥åå¨ä¸ä¸ªæå¤ä¸ªåå¸æ§½ï¼ä¹å°±æ¯è¯´å½åRedis Clusteræ¯æçæ大èç¹æ°å°±æ¯ãRedis Cluster使ç¨çåå¸å¼ç®æ³ä¹å¾ç®åï¼crc( key ) % HASH_SLOTS_NUMBERã
请ç¹å»è¾å ¥å¾çæè¿°
为äºä¿è¯åç¹æ éä¸çæ°æ®å¯ç¨æ§ï¼Redis Clusterå¼å ¥äºMasterèç¹åSlaveèç¹ãå¨Redis Clusterä¸ï¼æ¯ä¸ªMasterèç¹é½ä¼æ对åºç两个ç¨äºåä½çSlaveèç¹ãè¿æ ·å¨æ´ä¸ªé群ä¸ï¼ä»»æ两个èç¹çå®æºé½ä¸ä¼å¯¼è´æ°æ®çä¸å¯ç¨ãå½Masterèç¹éåºåï¼é群ä¼èªå¨éæ©ä¸ä¸ªSlaveèç¹æ为æ°çMasterèç¹ã
请ç¹å»è¾å ¥å¾çæè¿°
基于Redis实现点赞及排行榜功能
1.1、点赞相关需求:
1、同一个用户只能点赞一次,再次点击则取消点赞(点赞/取消点赞);
2、怎样深度学习源码如果当前用户已经点赞,则点赞按钮高亮显示(前端实现,判断字段Blog类的isLik属性)。
1.2、实现步骤:
1、给Blog类中添加一个isLike字段,标识是否被当前用户点赞;
2、修改点赞功能,指标源码为空利用Redis的set集合判断是否点赞过,未点赞过则点赞数+1,已点赞过则点赞数-1;
3、修改根据id查询Blog的业务,判断当前登录用户是否点赞过,赋值给isLike字;
4、修改分页查询Blog业务,判断当前登录用户是否点赞过,赋值给isLike字段。
1.3、点赞实现思路:
1.4、排行榜实现:
分析:由于需要对点赞功能进行排行榜分析,按照点赞时间先后排序,返回最早点赞的Top5的用户,所以最好是选择SortedSet实现功能。(特别说明:代码获取方式在文章结尾)
涉及到表信息:
2.1、zadd
案例:
2.2、zscore
案例:
2.3、zrem
案例:
2.4、zrange
案例:获取前四个元素
3.1、点赞/取消点赞功能
核心代码实现:
控制层:
接口调用:
结果展示:
3.2、排行榜功能
核心代码实现:
控制层:
接口调用及展示:
四、源码获取方式
更多优秀文章,请关注个人微信公众号或搜索“程序猿小杨”查阅。然后回复:源码,可以获取该项目对应的源码及表结构,开箱即可使用。
说明:后面redis相关操作的功能都会放在此文件夹中,需要相关功能的,只需要获取最新的资源即可。