一日一技:带过期时间的缓存、全文搜索、频率限制怎么做?

admin · 2022-05-30

  

  正在从前的著作内中,我给各人先容了利用Python自带的LRU缓存告竣带有过时韶华的缓存:一日一技:告竣有过时韶华的LRU缓存。也讲过倒排索引:利用倒排索引极速进步字符串寻找作用。但这些代码对初学者来讲对比难,写起来或者会失足。

  本质上,这些效用实在都能够利用Redis来告竣,况且每一个效用只要要1分钟就能做出来。全文寻找效用正在寻找英文的时辰,乃至能够智能辨认拼写过错的题目。

  要告竣这些效用,只要要做两件事:

   安置Redis

  Python安置第三方库:walrus

  安置实行往后,咱们来看看它有众简陋:

   带过时韶华的缓存掩饰器

  咱们思告竣一个掩饰器,它掩饰一个函数。让我正在1分钟内屡次探访函数的时辰,利用缓存的数据;超出1分钟往后才从新实施函数的外部代码:

  

importtimeimportdatetimefromwalrusimportDatabasedb=Database()cache=db.cache()@cache.cached(timeout=60)deftest():print(函数真正运转起来)now=datetime.datetime.now()returnnownow=test()print(函数前往的数据是:,now)time.sleep(10)#等候10秒,此时会利用缓存print(函数前往的数据是:,test())time.sleep(5)#等候5秒,此时仍然利用缓存print(函数前往的数据是:,test())time.sleep(50)#让韶华超出缓存的韶华print(函数前往的数据是:,test())

 

  运转恶果如下图所示:

  

   全文寻找

  咱们再来看看全文寻找效用,告竣起来也很简陋:

  

fromwalrusimportDatabasedb=Database()search=db.Index(xxx)#这个名字恣意取poem1=Earlyinthedayitwaswhisperedthatweshouldsailinaboat,onlythouandI,andneverasoulintheworldwouldknowofthisourpilgrimagetonocountryandtonoend.poem2=HadItheheavens’embroideredcloths,Enwroughtwithgoldenandsilverlightpoem3=tobeornottobe,thatisaquestion.search.add(docid1,poem1)#第一个参数不克不及反复search.add(docid2,poem2)search.add(docid3,poem3)fordocinsearch.search(end):print(doc[content])

 

  运转恶果如下图所示:

  

  假如你思让他兼容拼写过错,那末能够把search = db.Index(xxx)改为search = db.Index(xxx’, metaphone=True),运转恶果如下图所示:

  

  只是缺憾的是,这个全文寻找效用只维持英文。

   频率限度

  咱们偶然候要限度挪用某个函数的频率,或许网站的某个接口要限度IP的探访频率。这个时辰,利用walrus也能够轻松告竣:

  

importtimefromwalrusimportDatabasedb=Database()rate=db.rate_limit(xxx,limit=5,per=60)#每分钟只可挪用5次for_inrange(35):ifrate.limit(xxx):print(探访频率太高!)else:print(尚未触发探访频率限度)time.sleep(2)

 

  运转恶果如下图所示:

  

  此中参数limit显露能涌现若干次,per显露正在众长韶华内。

  rate.limit只消传入肖似的参数,那末就会起头查抄这个参数正在设定的韶华内涌现的频率。

  你或者感触这个例子并不克不及证明甚么题目,那末咱们跟FastAPI联络一下,用来限度IP探访接口的频率。编写如下代码:

  

fromwalrusimportDatabase,RateLimitExceptionfromfastapiimportFastAPI,Requestfromfastapi.responsesimportJSONResponsedb=Database()rate=db.rate_limit(xxx,limit=5,per=60)#每分钟只可挪用5次app=FastAPI()@app.exception_handler(RateLimitException)defparse_rate_litmit_exception(request:Request,exc:RateLimitException):msg={success:False,msg:f请喝杯茶,安歇一下,你的ip:{request.client.host}探访太疾了!}returnJSONResponse(status_code=429,content=msg)@app.get(/)defindex():return{success:True}@app.get(/important_api)@rate.rate_limited(lambdarequest:request.client.host)defquery_important_data(request:Request):data=要紧数据return{success:True,data:data}

 

  下面代码界说了一个整体的非常阻挡器:

  

@app.exception_handler(RateLimitException)defparse_rate_litmit_exception(request:Request,exc:RateLimitException):msg={success:False,msg:f请喝杯茶,安歇一下,你的ip:{request.client.host}探访太疾了!}returnJSONResponse(status_code=429,content=msg)

 

  正在全盘代码的任何处所掷出了RateLimitException非常,就会进入这里的逻辑中。

  利用掩饰器@rate.rate_limited掩饰一个途由函数,而且这个掩饰器要更凑近函数。途由函数摄取甚么参数,它就摄取甚么参数。正在下面的例子中,咱们只摄取了request参数,用于获取探访者的IP。创造这个IP的探访频率超出了限度,就掷出一个RateLimitException。因而后面界说好的整体阻挡器就会阻挡RateLimitException非常,阻挡到往后前往咱们界说好的报错讯息。

  正在频率规模内探访页面,前往平常的JSON数据:

  

  频率超出设定的值往后,探访页面就会报错,如下图所示:

  

   总结

  walrus对redis-py实行了很好的二次封装,用起来极度亨通。除了下面我提到的三个效用外,它还能够告竣几行代码天生布隆过滤器,告竣主动补全效用,告竣简单图数据库等等。各人能够探访它的官方文档认识精确利用证明[1]。

   参考文献

  [1] 官方文档认识精确利用证明: https://walrus.readthedocs.io/en/latest/getting-started.html

  本文转载自微信大众号「未闻Code」,能够经由过程如下二维码合心。转载本文请联络未闻Code大众号。

  

文章推荐:

回放今天cba篮球视频

13日什么台直播欧洲杯

怎么直播欧洲杯

cba授狐体育