#personalizedset
Explore tagged Tumblr posts
Text
Discover trendy pet accessories at CurliTail! Shop stylish, comfortable, and high-quality collars, leashes, and more for your furry friend. https://curlitail.com/
0 notes
Text
Shop the Vector Personalized Pet Toy Basket at CurliTail. Stylish, durable, and custom-made for your pet. Perfect for organizing toys. Made in the USA. https://curlitail.com/.../vector-personalized-pet-toy-basket

#personalizedset#PersonalizedPetBasket#PetToyBasket#PetOrganization#PetStorage#PetToyStorage#PetBasket#PetAccessories#CustomPetBasket
0 notes
Photo

Organic Pillow & Bolster Set Organic pillow & bolster set at little west street. Snugly soft organic pillow and bolsters for babyâs extra comfort. Grab some unique and attractive Kids accessories online that makes your kid shine
0 notes
Link
For just $148.00 --------------------------------------------- -------- SAVE $20 ------------ --------------------------------------------- CLASSIC MOTORCYCLES Original drawings prints Digitally printed on 200 grs acid free paper, professional quality. Image size 11 x 14 inches (for standard frames) The watermark not appear in prints. NOTE: Colors may vary from screen to screen. This price is for Registered shipment! Unframed Prints will be shipped in a cellophane sleeve. I send my prints off to their new home within 1-3 days of payment. I ship my international orders by air after I'm notified of your payment, and taking between 10 to 20 days to arrive. The purchase of any print does not transfer reproduction rights. ©Pablo Franchi -------------------------------------------------------------------------------------------------- Motorcycles BY YEAR: https://www.etsy.com/shop/drawspots?ref=hdr_shop_menu§ion_id=19206680 Motorcycles BLACK & WHITE: https://www.etsy.com/shop/drawspots?ref=hdr_shop_menu§ion_id=19206694 If you like CARS, take a look here: https://www.etsy.com/shop/drawspots/items?section_id=11083041 MUSICIANS, JAZZ portraits & quotes: https://www.etsy.com/shop/drawspots?section_id=11220720 ----------------------------------------------------------------------------------------------------
#CustomizableSet#HomeDecor#SetOfPrints#SetOf4#NortonBikes#ArtPrint#PersonalizedSet#BmwMotorcycles#OriginalDrawing#FathersDayPrint
0 notes
Photo

Gift Set of keychains for an upcoming wedding for the bride and groomð¹ #beautyandthebeast #customkeychains #couplesset #hisandhers #keychainset #pennykeychains #penny #custompenny #weddinggift #brideandgroom #hisbeautyherbeast #luckyinlove #initials #weddingday #daytocelebratelove #handstampedkeychain #personalizedset #personalizedkeychain #giftswithmeaning #makingthingspersonal #sibellejewelry
#hisbeautyherbeast#pennykeychains#keychainset#makingthingspersonal#personalizedkeychain#initials#handstampedkeychain#beautyandthebeast#hisandhers#customkeychains#weddinggift#giftswithmeaning#personalizedset#weddingday#couplesset#daytocelebratelove#sibellejewelry#luckyinlove#penny#brideandgroom#custompenny
0 notes
Text
ãªããžã§ã¯ãæåããã°ã©ãã³ã°ã«ããã Redis Sorted Set ã®æœè±¡å
ïŒæ¬çš¿ã¯ æè¡æžå±4 ã«ãŠé åžããã WANTEDLY TECH BOOK 4 ã«æ²èŒãããäºå®ã®æç« ã§ãïŒ
ã¯ããã«
Redis ã® Sorted Set ã䜿ã£ãäžèЧç»é¢ã®å®è£
ãã¿ãŒã³
Web ãµãŒãã¹ã«ãã㊠Redis ã® Sorted Set ã¯é«éãªã©ã³ãã³ã°ã®å®çŸã®ããã«ãã°ãã°çšãããããã©ã³ãã³ã°ã»ããŒã¿ã Redis ã«èŒããããšã§ãé«éãªããŒã¿ã®ååŸã»ããŒãžã³ã°ã»ä»¶æ°èšç®ãªã©ãå¯èœã«ãªããã©ã³ãã³ã°ã®ããã«é åºä»ããããã³ã³ãã³ã㯠Web ãµãŒãã¹ã®äžèЧç»é¢ãšåŒã°ããããŒãžã«ãããŠååšãããããã®ãããªç»é¢ã«ãããŠã¯ãã°ãã°ãªãã³ã·ã§ã³ãéèŠã§ãããã¬ã¹ãã³ã¹é床ã¯ãã®ãªãã³ã·ã§ã³ã«å¯ŸããŠåœ±é¿ãäžãããããé«éãªå®è£
ãæ±ããããã
äžæ¹ãæç³»åã§èããå ŽåãäžèЧç»é¢ã®èŠä»¶ã¯ãµãŒãã¹ã®æ±ãã³ã³ãã³ãæ°ãå¢å ããã«åŸã£ãŠè€éåãããäŸãã°ããŠãŒã¶ãŒãé©åãªã³ã³ãã³ããçºèŠã§ããããã«ããå¿
èŠãåºãŠããŠããã®ããã«æ§ã
ãªæ¡ä»¶ã«ããçµã蟌ã¿ãæ€çŽ¢ããããã¯ããŒãœãã©ã€ãºãããæšèŠãšèšã£ãæ©èœãå¿
èŠã«ãªã£ãŠããã
ãããã®æ©èœãã©ã®ããã«å®çŸãããè¯ãã ããããéåžžãçµã蟌ã¿ã«äœ¿ããããããªã³ã³ãã³ãã®ããŒã¿ã¯ãªã¬ãŒã·ã§ãã«ããŒã¿ããŒã¹ã«ä¿åãããŠãããäžæ¹ã§ãæ€çŽ¢ã®å®çŸã«ã¯ Elasticsearch ãªã©ã®å
šææ€çŽ¢ãšã³ãžã³ãæ¡çšãããããšãå€ãããŸããæšä»ã§ã¯æ©æ¢°åŠç¿ã掻çšãããããšãå€ããããã®ãããªåŠçãè¡ãããã®ã©ã€ãã©ãªã¯ Python ãå
å®ããŠããããã®ããã«ããŠãŒã¶ãŒã«äŸ¡å€ãæäŸã§ããäžèЧç»é¢ã«æ±ããããæ©èœã¯å€ãããŸããããå®è£
ããããã«æé©ãªæè¡ã¯å¿
ãããäžã€ã«ã¯å®ãŸããªãã
ãã€ã¯ããµãŒãã¹ã»ã¢ãŒããã¯ãã£ãæ¡çšããŠããå Žåãåæ©èœãå®çŸããã®ã«æé©ãªæè¡ã«åºã¥ãããã€ã¯ããµãŒãã¹ãå®è£
ããããããçµã¿åãããããšã«ãã£ãŠäžèЧç»é¢ãå®çŸããããšãèãããããããããã®ãšããåãã€ã¯ããµãŒãã¹ãã©ã®ãããªæ¹æ³ã§çµ±åããã®ããšããããšã課é¡ã«ãªãã
æ¢ã«è¿°ã¹ãããã« Redis ã® Sorted Set ã¯ã©ã³ãã³ã°ã«å©çšãããããšãå€ãããåéåã»ç©éåãªã©çµã¿èŸŒã¿ã®éåæŒç®ã®åœä»€ã䜿ãããšã§çµã蟌ã¿ãæ€çŽ¢ããããã¯ããŒãœãã©ã€ãºãšèšã£ãããé«åºŠãªæ©èœãå®çŸããããšãã§ãããããã§ãç°ãªãã·ã¹ãã ããéããæ
å ±ãããããå¥åã® Redis ã® Sorted Set ã«ãã£ãã·ã¥ããäžã§ããããéçŽèšç®ããŠäžèЧç»é¢ã«å¿
èŠãªæ
å ±ãç®åºãããããªæ§æãèããããšãã§ããã
ãã®æ§æã§ã¯ãä»»æã®ãã€ã¯ããµãŒãã¹ãããŒã¿ããŒã¹ããã®æ
å ±ãã¹ã³ã¢ä»ãã®éåãšã¿ãªããäžã§çµ±åããããšãã§ããããŸããã¬ã¹ãã³ã¹ã«å¿
èŠãªå
šãŠã®ããŒã¿ã¯äžåºŠ Redis ã«ä¹ããããèšç®ã®å
å®¹ãæ§ã
ã§ããåã·ã¹ãã 矀ããµãŒãã¹ãšããŠæ±ããããŠããã¬ã¹ãã³ã¹é床ãçŽæ¥æºãããªããŠãå
šäœãšããŠé«éã«åäœãããšèšã£ãå©ç¹ãããã
äºäŸ
Wantedly Visit ã§ã¯æ°åäžä»¶ã®åéãååšãããããã®äžèЧç»é¢ïŒ https://www.wantedly.com/projects ïŒã¯äžèšã®ãããªèŠä»¶ãæã€äžäŸã§ããããã®ç»é¢ã¯å®éã«ãã®æ§æãšãããã玹ä»ãã RedBlocks ã䜿ã£ãŠå®çŸãããŠããã
å®çŸããäžã§ã®èª²é¡
課é¡1: ãªããžã§ã¯ãæåããã°ã©ãã³ã°ãš Redis ã®ã³ãã³ãäœç³»ã®ã€ã³ããŒãã³ã¹ã»ãã¹ããã
ãã®ããã« Redis ã® Sorted Set ãçšããããšã§äžèЧç»é¢ã«å¿
èŠãªæ©èœãå®çŸããããšãã§ããããã ãããã®å®è£
ã Redis ã®ã³ãã³ãããã®ãŸãŸåŒã³åºã圢ã§è¡ããšãRuby ãªã©ã®ãªããžã§ã¯ãæåããã°ã©ãã³ã°èšèªã«æŒããŠã¯é«ãå¯èªæ§ã»å€æŽå®¹ææ§ãå®çŸããããšãã§ããªãã
å
·äœçã«ã¯ãRedis ã®ã³ãã³ãäœç³»ãåœä»€çãªãã®ã§ãããããããããã®ãŸãŸå©çšãããšæç¶ãçãªããã°ã©ã ã«ãªã£ãŠããŸãããã®åé¡ã¯ã åçŽãªãã£ãã·ã¥ç®çã§ Redis ãå©çšããŠãããšãã«ã¯å€§ããåé¡ã«ãªããªãããä»åè¿°ã¹ãããã«è€éãªã·ã¹ãã ãæ§ç¯ããéã«ã¯åé¡ãšãªããå
·äœçã«ã¯ãäœãã¢ããªã±ãŒã·ã§ã³ã®å€æŽãè¡ããšãã«å€æŽç®æãèŠã€ãåºãããšãé£ããã£ãããè€æ°ã®ç®æã倿Žããå¿
èŠãçããïŒå€æŽã«å¯ŸããŠã¢ãžã¥ã©ã§ãªããé¢å¿ãåé¢ãããŠããªãããšèšã£ãç¶æ
ã«ãªãïŒã
# éåžžã«åçŽãªéåæŒç®ãæžãã ãã§ãå€ãã®åœä»€ãå¿
èŠã«ã«ãªã c = Redis.new c.zadd("src1", [[32.0, "a"], [64.0, "b"]]) c.expire("src1", 60) c.zadd("src2", [[44.0, "a"], [21.0, "c"]]) c.expire("src2", 60) c.zinterstore("dest", ["src1", "src2"]) c.expire("dest", 10) c.zrevrange("dest", 0, 5) #=> ["a"] c.zcard("zcard") #=> 1
éåžžããªã¬ãŒã·ã§ãã«ã»ããŒã¿ããŒã¹ããªããžã§ã¯ãæåã®èšèªããå©çšããå Žåãéåæåãšã®æŠå¿µçãªå·®ç°ïŒããŸãè¯ãã¡ã¿ãã¡ãŒãšã¯èšããªãããã€ã³ããŒãã³ã¹ã»ãã¹ãããããšåŒã¶ããšãããã®ã§æ¬çš¿ã§ãçšããïŒãåé¡ã«ãªããããO/R Mapper ã«ããæœè±¡åãè¡ã£ãäžã§å©çšããããšãå€ããåæ§ã®çç±ã§ãRedis ã® Sorted Set ã Ruby ããå©çšããéã OOP ã«å³ããåœ¢ã§æœè±¡åãè¡ãããšã§ãã®åé¡ã解決ããããšãå¿
èŠã«ãªãã
è§£æ¶ãã¹ãå·®ç°ã®äŸãšããŠãã¯ã©ã¹ããŒã¹ã® OOP ã«ãããŠã¯ãã¯ã©ã¹ã¯ããèªäœã§çŽæ¥ã¢ããªã±ãŒã·ã§ã³ã«å¿
èŠãªä»äºãæããããã§ã¯ãªããã€ã³ã¹ã¿ã³ã¹åãéããŠãããè¡ããRedis ã® Sorted Set ã«ã¯ã©ã¹ãšã€ã³ã¹ã¿ã³ã¹ã®ãããªæŠå¿µã¯ç¡ããããkey ã®éå±€åãéããŠãããå®è£
ããå¿
èŠãããã
課é¡2: å®è£
ã«å¿
èŠãªå€ãã®è©³çް
å®éã«ãµãŒãã¹ã§å©çšããããã«ã¯æŠå¿µçãªå·®ç°ä»¥å€ã«ãå€ãã®é èœã§ããå®è£
詳现ããããäŸãã°ã次ã®ãããªããšã¯æ¬æ¥ãéœåºŠã¢ããªã±ãŒã·ã§ã³ãéçºããããã°ã©ããèããå¿
èŠã®ãªãããšã§ããã
ãã£ãã·ã¥ã®ååšã®æç¡ããã§ãã¯ããŠãªããã°ããŒã¿ãååŸã Redis ã«ä¿åãã
ãã£ãã·ã¥ãç¡ãæéãååšããªãããã«å·®åæŽæ°ã«ãã
çŽåäŸåæ§ã®ãªãã³ãã³ãã®ãã€ãã©ã€ã³å®è¡
Redis ã® key ã«äœ¿ãåå
ãã®ãããªå®è£
詳现ãé èœããããšã§ãã¢ããªã±ãŒã·ã§ã³ãéçºããéã
1) ãµãŒãã¹ã®ä»æ§ãšããŠåãã€ã¯ããµãŒãã¹ãã©ãçµã¿åããããïŒAND ãªã®ã OR ãªã®ããã¹ã³ã¢ãã©ãçµã¿åããããïŒ
2) ããããã®èšç®æ®µéã«ãããããŒã¿ãã©ã®çšåºŠãã£ãã·ã¥ããã
ãšèšã£ãçµ±åã«é¢ãã仿§ïŒããã¯ãµãŒãã¹ã®äŸ¡å€ã«çŽçµããïŒã«ããã°ã©ãã¯éäžã§ããããã«ãªãã
RedBlocks
å
·äœçã«äžèšã®ãããªåé¡ã解決ããããã«ããRedBlocks ãšãã Ruby ã©ã€ãã©ãª(gem)ãçšæããã
以éã§ã¯ãRedBlocks ãéããŠã©ã®ããã«è€æ°ã®ã·ã¹ãã ãçµã¿åããããããå®éã®äžèЧç»é¢ã®å®è£
ãéããŠç޹ä»ããããã®åŸãããã€ãã®å®è£
詳现ã«ã€ããŠèšåããæåŸã«ãŸãšããšããã
Case Study: RedBlocks ãçšããäžèЧç»é¢ã®å®è£
ãã®ç« ã§ã¯ã課é¡1ãšããŠè¿°ã¹ããªããžã§ã¯ãæåããã°ã©ãã³ã°ãš Redis ã®ã³ãã³ãäœç³»ã®ã€ã³ããŒãã³ã¹ã»ãã¹ããããã©ã®ããã«è§£æ±ºã§ããŠããã®ããå®äŸãéããŠèª¬æããããã®ããã«ã次ã®ãããªäžèЧç»é¢ãæ³å®ããã
ãã®ç»é¢ã«ã¯ãäž»ã«æ¬¡ã®4ã€ã®æ©èœãåãã£ãŠããããŸããå
±éããæ©èœãšããŠä»¶æ°è¡šï¿œï¿œãšããŒãžã³ã°ãã§ããã
ã©ã³ãã³ã°ïŒåæç¶æ
ïŒ
çµã蟌ã¿
å
šææ€çŽ¢
ããŒãœãã©ã€ãºïŒãŠãŒã¶ãŒç»é²ããŠå©çšããŠããå ŽåïŒ
ãããã®æ©èœãé æ¬¡å®è£
ããŠãããæåŸã«ããããŠãŒã¶ãŒã®æäœã«å¿ããŠè¡ã service ã¯ã©ã¹ãå®è£
ããã
1. ã©ã³ãã³ã°
ã»ãŒå
šãŠã®ãµãŒãã¹ã«ãããŠãäžèЧç»é¢ã§ã¯ã³ã³ãã³ãïŒä»¥äžãèŠçŽ ïŒãã©ã®ãããªåªå
床ã§è¡šç€ºããã®ããšããããšãèããå¿
èŠããããããã¯ã©ã³ãã³ã°ã«çžåœãããå
šãŠã®ãŠãŒã¶ãŒã«åãé çªã§èŠããå Žåãã©ã³ãã³ã°ãäžã€ã ãçšæããã°è¯ããã©ã³ãã³ã°ã¯ãããããã®èŠçŽ ã«å¯ŸããŠã¹ã³ã¢ãä»ããéåããšæãããããããRedis ã® Sorted Set ãå©çšããŠå®è£
ããããšãã§ããã
ããã§ã¯ãäžèЧç»é¢ãæ±ãèŠçŽ ãšããŠåéïŒProjectïŒãæ³å®ããäžã§ãã«ã©ã ãšã㊠monthly_page_view ãæã£ã Project ãšããActiveRecord ã¢ãã«ããããããšããããã®ã«ã©ã ã®å€ãå©çšã㊠PV ããŒã¹ã®ã©ã³ãã³ã°ãäœæãããããã®ããã® RedBlocks ãçšããã³ãŒãã¯æ¬¡ã®ããã«ãªãã
class PageViewSet < RedBlocks::UnitSet def cache_time RedBlocks::CachePolicy.hourly end def get Project.pluck(:id, :monthly_page_view) end end
ãã®ã³ãŒãã¯ããŸã RedBlocks::UnitSet ãç¶æ¿ããããšã§éåïŒSorted SetïŒã衚ãã¯ã©ã¹ PageViewSet ãå®çŸ©ããŠããããã®éåã¯èŠçŽ ãšããŠãæéããŒãžãã¥ãŒãã¹ã³ã¢ã«æã£ãåéå«ãã§ããã
ãã®ã¯ã©ã¹ãå©çšããããšã§ãäŸãã°æ¬¡ã®ããã«ã©ã³ãã³ã°ã®å
é 5ä»¶ãååŸã§ããã
pv_set = PageViewSet.new pv_set.ids #=> [1942, 3921, 354, 1120, 4931] pv_set.size #=> 5121
ids ã¡ãœãããåŒã°ãããšãåå㯠get ã¡ãœããã®åŒã³åºããéã㊠Project ã¯ã©ã¹ããã¯ãšãªãçºè¡ãããããã®çµæã¯ Sorted Set ãšããŠãã£ãã·ã¥ãããäžã§ãids ã¡ãœããã®è¿ãå€ãšãªããäºåç®ä»¥éã® ids ã¡ãœããã®åŒã³åºãã§ã¯ãã£ãã·ã¥ãå©çšãããããéåžžã«é«éã«è¿ããåæ§ã«ãå
šäœã®ä»¶æ°ã size ã¡ãœãããéããŠãã£ãã·ã¥ãããéåãã宿°æéã§ååŸããããšãã§ããã ãŸããids ã¡ãœããã« paginator ãªããžã§ã¯ããæž¡ãããšã§ã宿°æéã§ã®ããŒãžããŒã·ã§ã³ãå¯èœã«ãªããå®éã® Web ãµãŒãã¹ã®å®è£
ã§ã¯ããªã¯ãšã¹ããã©ã¡ãŒã¿ãšããŠæž¡ã£ãŠããããŒãžçªå·ããã®ãŸãŸæž¡ãããšãå€ããšæãããã
ãã®ãã£ãã·ã¥ãã©ã®çšåºŠã®æé Redis äžã«ä¿æããã㯠cache_time ã¡ãœããã«ãã£ãŠæ±ºããããšãåºæ¥ãããã®ã¡ãœãããå®çŸ©ããªãå Žåããã£ãã·ã¥ããæéã¯ãŒããšãªããããŒã¿ã¯ Redis äžã«ã¯æäœéã®æéããçåããªãïŒãã£ãã·ã¥ããªãå Žåã§ã Redis äžã«ããŒã¿ãçåããå¿
èŠãããçç±ã¯åŸè¿°ããïŒã
cache_time ã¯é®®åºŠãã³ã¹ãã«å¿ããŠå¿
èŠã§ããã°å®çŸ©ããã°è¯ãã®ã§ããã以éã®ãµã³ãã«ã³ãŒãã§ã¯çç¥ããã
2. çµã蟌ã¿
å°åã®åéã®éå - RedBlocks::Set ã®å©çš
ãµãŒãã¹ã®ã³ã³ãã³ããå¢å ããŠããããšã§ãåéãå°åã«ãã£ãŠçµãèŸŒãæ©èœãæäŸããããªã£ããšããããå°åã¯ããåæµ·éããæ±åãã颿±ããåéžããç²ä¿¡ï¿œï¿œï¿œããæ±æµ·ããè¿ç¿ããäžåœããååœããä¹å·ããæ²çžãã®11å°åã«åé¡ããããšããããã®ããã«ããŸãã¯å°åããšã®åéã®éåã衚ãã¯ã©ã¹ãå®çŸ©ããã
class RegionSet < RedBlocks::Set def initialize(region) raise ArgumentError unless Project::REGIONS.include?(region) @region = region end def key_suffix @region end def get Project.where(region_cd: @region).pluck(:id) end end
ãã®ã¯ã©ã¹ã¯æ¬¡ã®ããã«å
·äœç㪠region ãåŒæ°ã«äžããŠã€ã³ã¹ã¿ã³ã¹åããããšã§ãå
ã»ã©ã®ã©ã³ãã³ã°éåã®å Žåãšåæ§ã«å©çšããããšãã§ããã
set = RegionSet.new('hokkaido') set.ids #=> [1, ... ] # åæµ·éã®åéã®ãªã¹ã
PageViewSet ãš RegionSet ã®éãã¯ãPageViewSet 㯠RedBlocks::UnitSet ãç¶æ¿ããŠããã®ã«å¯Ÿã㊠RegionSet 㯠RedBlocks::Set ãç¶æ¿ããŠããç¹ãšãRegionSet 㯠key_suffix ã¡ãœãããå®è£
ããŠããç¹ã«ããã
RegionSet ã¯åå°åã«å¯ŸããŠããããç°ãªãéåãããåŸããããã€ã³ã¹ã¿ã³ã¹ãšããŠçæããéã«å
·äœçãªå°åã®æå®ãå¿
èŠã§ãããæŽã«ãRedis ã«ä¿åããéã®ä¿åå
ããäŸãã°ãåæµ·éå°åã®åéã®éåããšã颿±å°åã®åéã®éåãã§ã¯ç°ãªãããããã®ä¿åå
ãæå®ããããã® Redis ã® key ã®1éšåãšã㊠key_suffix ã¡ãœãããå®è£
ããå¿
èŠããããkey_suffix ã¡ãœããã¯ã€ã³ã¹ã¿ã³ã¹ã¬ãã«ã§ç°ãªãéåãåºå¥ã§ãããããªæååãè¿ãããã«å®è£
ããå¿
èŠãããã
äžæ¹ãæåã«ç޹ä»ãã PageViewSet ã¯å®è³ªçã«ã¯ã©ã¹ã«ãã äžã€ã®éåããäœãåŸãªãã·ã³ã°ã«ãã³éåã§ãã£ããããããã«ç¹æ®åãã RedBlocks::UnitSet ãå©çšããããã®ã¯ã©ã¹ã¯ã·ã³ã°ã«ãã³ãåæãšããŠãããããkey_suffix ã¡ãœãããå®è£
ããå¿
èŠã¯ãªãã
ãŸããget ã¡ãœããã®è¿ãå€ã®åã«çç®ããŠã¿ããšãPageViewSet#get ã¯åéã® id ãšã¹ã³ã¢ã®ãã¢ã®ãªã¹ããè¿ããŠããããRegionSet#get ã¯ãã åéã® id ã®ãªã¹ããè¿ããŠããããšãåãããRedBlocks ã® get ã¡ãœããã§ã¯ãid ã®ãªã¹ããè¿ããå Žåã«å
éšçã«å
šãŠã¹ã³ã¢0ã® Sorted Set ãšããŠæ±ããRedis ã®éåæŒç®ã§ã¯ã¹ã³ã¢ã¯ããã©ã«ãã§åäžèŠçŽ å士ã§å ç®ããããããã¹ã³ã¢ãæé»çã«é¶å
ã«èšå®ããŠããããšã§ã¹ã³ã¢ã«åœ±é¿ãäžããªãéåãšããŠæ±ãããšãã§ãããããã°ã©ãã¯ãã¹ã³ã¢ãæããªãïŒã€ãŸãæ°åŠçãªæå³ã§ã®ïŒéåãå©çšããããšãã«ã¯ãã èŠçŽ ã®ãªã¹ããè¿ãã ãã§è¯ããä»åã®å Žåãå°åã«ããçµã蟌ã¿åäœã¯é åºã«ã¯é¢äžããªã仿§ã«ããããããRegionSet#get ã¯ãã èŠçŽ ã®ãªã¹ããè¿ããŠããã
è€æ°ã®å°åã«å«ãŸããåéã®éå - RedBlocks::UnionSet ã®å©çš
ãããŸã§ã§ç¹å®ã®å°åã«ããçµã蟌ã¿ãã§ããããã«ãªã£ãããããåæµ·éããŸãã¯ã颿±ãã®åéãæ¢ãããããšèšã£ããŠãŒã¶ãŒã®ããŒãºã«ãå¿ããããããã«ãããïŒãŠãŒã¶ãŒã»ã€ã³ã¿ãŒãã§ãŒã¹ãšããŠã¯ããã§ãã¯ããã¯ã¹ã®ããã«è€æ°éžæåŒã®ãã®ã«ãªãïŒã
ããã¯ãéåã§èšãã°åæµ·éã®åéãšé¢æ±ã®åéã®åéåãäœãããšã«çžåœãããåŸã£ãŠã次ã®ãããªå®åŒåãã§ããïŒ
[åæµ·éã®åé] ⪠[颿±ã®åé]
RedBlocks::UnionSet ã䜿ãããšã§ããã®åéåæŒç®ãå®çŸã§ããã
region1_set = RegionSet.new('hokkaido') region2_set = RegionSet.new('kanto') regions_set = RedBlocks::UnionSet.new([region1_set, region2_set]) regions_set.ids #=> [921, 324, 21, 39, 101]
å
¬éãããŠããåéã®ã¿ã«çµã - RedBlocks::IntersectionSet ã®å©çš
å®éã®ãµãŒãã¹ã§ã¯ãã³ã³ãã³ãã«ã¯äžæžãã»éå
¬éãªã©ã®ç¶æ
ãååšããå¿
ãããããŒã¿ããŒã¹ã«ç»é²ãããŠããå
šãŠã®ã³ã³ãã³ããäžèЧç»é¢ã«åºããããã§ã¯ãªï¿œï¿œããã®ããšãå¶åŸ¡ãããããæ¬¡ã®ããã«å
¬éåéã®éåã§ç©éåæŒç®ãè¡ã£ãçµæãåžžã«è¿ãããã«ãããïŒ
[å
¬éãããŠããåé] â© ([åæµ·éã®åé] ⪠[颿±ã®åé])
RedBlocks::IntersectionSet ã䜿ãããšã§ããã®ç©éåæŒç®ã¯å®çŸã§ããã
visible_set = VisibleSet.new result_set = RedBlocks::IntersectionSet.new([visible_set, regions_set])
ããŠãå
¬éã»éå
¬éãªã©ã®ç¶æ
ã®å€æŽã¯ç¹ã«ãªã¢ã«ã¿ã€ã ã§äžèЧç»é¢ã®çµæã«åæ ããããã®ã§ããããã®ãããåéã®ç¶æ
ã®å€æŽã«å¿ã㊠RedBlocks::Set#update! ãåŒã³åºããŠå³åº§ã«ãã£ãã·ã¥ãæŽæ°ããããã«ããã
class Project < ActiveRecord::Base # ... after_save -> { VisibleSet.new.update! }, if: -> { visibility_changed? && visible? } end
çµã蟌ã¿çµæã PV ã§ãœãŒããã
å°åã«ããçµã蟌ã¿ãè¡ã£ãçµæããçµã蟌ãåã®æåã«ç޹ä»ãã PV ã©ã³ãã³ã°ã«åºã¥ããŠè¡šç€ºãããããã«ããããããã¯ãæåã«äœæãã PageViewSet ãç©éåæŒç®ã«çµã¿èŸŒãããšã§å®çŸã§ããã
[PageView ãã¹ã³ã¢ã«æã€åé] â© [å
¬éãããŠããåé] â© ([åæµ·éã®åé] ⪠[颿±ã®åé])
PageView ã§ã¯ãªãææ°é ã§è¡šç€ºãããšèšã£ããœãŒãæ¡ä»¶ã®åãæ¿ãæ©èœãæäŸããã®ã§ããã°ããã®ç©éåæŒç®ã«äœ¿ãã¹ã³ã¢ä»ãéåã倿Žããã°è¯ãã
[å
¬éæ¥æãã¹ã³ã¢ã«æã€åé] â© [å
¬éãããŠããåé] â© ([åæµ·éã®åé] ⪠[颿±ã®åé])
3. å
šææ€çŽ¢
ãµãŒãã¹ã«ååãªã³ã³ãã³ãéãšåå倿§ãªãŠãŒã¶ãŒãéãŸã£ããããä»»æã®ããŒã¯ãŒãã«ããæ€çŽ¢æ©èœãå
¥ããŠããç®çã®åéã«åºäŒãããããããããããŸã§ã®èšç®ã¯ãªã¬ãŒã·ã§ãã«ã»ããŒã¿ããŒã¹ã®ããŒã¿ãå
ã«ããŠããããä»åã®æ©èœè¿œå ã§ã¯ããããã床ãé«ãèŠçŽ ããé çªã«ãŠãŒã¶ãŒã«è¡šç€ºããããããå
šææ€çŽ¢ãšã³ãžã³ Elasticsearch ãžåãåãããçµæã®ã¹ã³ã¢ãæ¡çšããããšã«ããã
ãã®ããã«ç¹å®ã®ããŒã¯ãŒããåŒæ°ã«åãåã£ãŠ Elasticsearch ã«åãåãããæ¬¡ã®ãããªã¢ãžã¥ãŒã«ãäœæãããElasticsearch ã«ã¯åéã®ããã¹ãæ
å ±ãåæããŠããã
ProjectSearchService.new("Ruby", format: :id_with_score).perform #=> [[32, 12.1], [811, 11.0], ...]
ãã®ã¢ãžã¥ãŒã«ãå
ã«ãRegionSet ã®å Žåãšåæ§ã«éåãå®çŸ©ãããRegionSet ãšã®éãã¯ãå
šéšæ€çŽ¢ã«ãã該åœããŒã¯ãŒããžã®ããã床ãå
¥ã£ãã¹ã³ã¢ä»ãã®éåãšãªã£ãŠããç¹ã«ããã
class KeywordSet < RedBlocks::Set def initialize(keyword) @keyword = keyword end def key_suffix @keyword end def get ProjectSearchService.new(@keyword, format: :id_with_score).perform end end
ãã® KeywordSet ãçšããŠãäŸãã°æ¬¡ã®ãããªéåãæ§ç¯ã§ããã°ããŒã¯ãŒãæ€çŽ¢æ©èœãä»å ããããšãã§ãããããŒã¯ãŒãã«ããã¹ã³ã¢ãæ¢ã«ä»ããŠãããããããã§ã¯PVã©ã³ãã³ã°ã®éåã¯å©çšããŠããªãã
// ããŒã¯ãŒãã ãã§çµã蟌ã [å
¬éãããŠããåé] â© [ããŒã¯ãŒãã§çµã蟌ãã éå] // å°åãšããŒã¯ãŒãã§åæã«çµã蟌ã [å
¬éãããŠããåé] â© ([åæµ·éã®åé] ⪠[颿±ã®åé]) â© [ããŒã¯ãŒãã§çµã蟌ãã éå]
4. ããŒãœãã©ã€ãº
ãŠãŒã¶ãŒã®è¡åããŒã¿ãååã«è²¯ãŸã£ãã®ã§ããããå
ã«ããŠããããã®ãŠãŒã¶ãŒã«åã£ãã³ã³ãã³ããæšèŠããããšãããããã®å ŽåããããŠãŒã¶ãŒãããããã®ã³ã³ãã³ããã©ã®çšåºŠå¥œãã®ãã®äºæž¬æ°å€ãã¹ã³ã¢ãæã€ãããªéåãå®çŸ©ããããã®èšç®ã¯å€§èŠæš¡ãªãã°ããŒã¿ã«ã¢ã¯ã»ã¹ããä»ã®ãã€ã¯ããµãŒãã¹ãè¡ã£ãŠããå¯èœæ§ãããããéåãšããŠæœè±¡åã§ãããšããç¹ã¯å€ãããªãã
class PersonalizedSet < RedBlocks::Set def initialize(user_id) @user_id = user_id end def key_suffix @user_id end def get RecommendationService.get_personalized_ranker end end
ããã§å®çŸ©ãã PersonalizedSet ã®äœ¿ãæ¹ã¯è²ã
ãªå¯èœæ§ããããã»ãŒå
šãŠã®åéã«å¯ŸããŠããçšåºŠåŠ¥åœãªäºæž¬æ°å€ãä»ããããã®ã§ããã°åç¬ã§ã¹ã³ã¢ä»ãã«å©çšã§ãããããããªãããäžéšã®åéã«å¯ŸããŠã ãäºæž¬æ°å€ãä»ããŠä»ã¯ãŒãã«ãªã£ãŠãããããªï¿œï¿œï¿œãªéåã§ããã°ã0..1 ã«æ£èŠåããäžã§äžè¬çãªäººæ°åºŠãã¹ã³ã¢ã«æã€éåãšè¶³ãåãããŠå©çšã§ãããããããªãã念ã®ããå®åŒåãããšã次ã®ããã«ãªãïŒ
[å
¬éãããŠããåé] â© [ããŒãœãã©ã€ãºãããã¹ã³ã¢ãæã€éå] â© ïŒãã®ä»ã®çµãèŸŒã¿æ¡ä»¶ïŒ // ããŒãœãã©ã€ãºã ã [å
¬éãããŠããåé] â© [ããŒãœãã©ã€ãºãããã¹ã³ã¢ãæã€éå] â© [äžè¬çãªäººæ°åºŠãã¹ã³ã¢ã«æã€éå] â©ïŒãã®ä»ã®çµãèŸŒã¿æ¡ä»¶ïŒ// ããŒãœãã©ã€ãº + 人æ°åºŠ
5. å
šãŠã®çµ±å
ãããŸã§ãRedBlocks ãçšããŠå®çŸ©ããéåãçµã¿åãããããšã§ãæ§ã
ãªæ©èœãå®çŸã§ããããšãèŠãŠãããå®éã®ãµãŒãã¹ã§ã¯ãããããŠãŒã¶ãŒã®å
¥åã«å¿ããŠåçã«è¡ãå¿
èŠãããããããäŸãã°æ¬¡ã®ãã㪠service ã¯ã©ã¹ãäœæããããšã§è¡ãã
class ProjectListingService def new(params, user_id: nil) # ... @set = build_set(params, user_id) end def fetch(per: 10, page: 1, format: :ids) paginator = build_paginator(per, page) case format when :ids then set.ids(paginator) when :count then set.size end end private def build_set(params, user_id) sets = params.each do |k,v| ... end sets << VisibleSet.new sets << PersonalizedSet.new(user_id) if user_id RedBlocks::IntersectionSet.new(sets, cache_time: 10.minutes) end end
ããã§ãæ°ãã« RedBlocks::IntersectionSet ã« cache_time ãªãã·ã§ã³ã远å ããŠããããšã«æ³šæãããããããŸã§ãRedBlocks::IntersectionSet ã RedBlocks::UnionSet ãšèšã£ãåæåã®éåã«ã€ããŠãããã©ã®çšåºŠã®æéãã£ãã·ã¥ãããã®ãã«ã€ããŠã¯èšåããŠããªãã£ãããå®ã¯ããã©ã«ãã§ã¯èšç®ã«å¿
èŠãªæäœéã®æéããçåããªããããããã®ã³ãŒãã§ã¯ãçµã蟌ã¿ãªã©ãè¡ã£ãäžã§ã®ããŒãžã³ã°ãåèšç®ããé«éã§è¡ãããããã«ãæçµçãªåºåçµæã«å¯ŸããŠã¯10åéã®ãã£ãã·ã¥ãè¡ãããã«èšå®ããŠããã
倿Žã«å¯Ÿããã¢ãžã¥ã©æ§ã®æ€èš
ããŠããããŸã§ã§ RedBlocks ãã€ããããšã§äžèЧç»é¢ãã©ã®ããã«å®è£
ããããããããèŠãããšãã§ããããã®å®è£
æ¹æ³ã«ã€ããŠå€æŽã«å¯Ÿããã¢ãžã¥ã©æ§ã®èгç¹ããã©ã®ãããªæ¹åãã§ããã®ããããåŸã倿Žã«å¯ŸããŠã©ã®ããã«é¢å¿ãåé¢ã§ããŠããããæããã«ããŠããããã
åæ§ã®ããžãã¯ãæã€éåãã¯ã©ã¹ããŒã¹ã§ãŸãšãäžããããšãã§ããïŒäŸïŒå°åã¯ã©ã¹ - åæµ·éã€ã³ã¹ã¿ã³ã¹ïŒ
ããã«ãããæ°ããªå°åãçµã蟌ã¿é
ç®ã«è¿œå ããéã«ã¯ããããå°åã®ãªã¹ãã«è¿œå ããã ãã§æžãããã«ãªã
åãµãã·ã¹ãã ãžã®ã¢ã¯ã»ã¹ãã¯ã©ã¹ã® get ã¡ãœããã«æœè±¡åããã
ããã«ããããµãã·ã¹ãã ã®çœ®ãæããšèšã£ã倿Žã get ã¡ãœããã®å®è£
ã«å±æåãããããšã«ãªã
é床çãªæé©åã¯æé»çãªãã£ãã·ã¥ã«ããè¡ããã
ããã«ãããé
ããµãã·ã¹ãã ã«ã¯ãã£ãã·ã¥ãå
¥ããããšèšã£ãããžãã¯ã«é¢ä¿ã®ãªãã³ãŒããçç¥ããã
ããŒã¿ãåŒãéšåã Set ã¯ã©ã¹ãçµ±åã ProjectListingService ã§è¡ããšããåé¢ãã§ããŠãã
ããã«ããããèšèªããšèšã£ãå
šãæ°ããçµã蟌ã¿é
ç®ã远å ããéãä»ã® Set ã¯ã©ã¹ã¯äžå倿Žããã«æžã
å
·äœçã«ã¯ 1) æ°èŠã« LanguageSet ã¯ã©ã¹ãå®çŸ©, 2) Service ã¯ã©ã¹ã®å€æŽ ã®2ç¹ãè¡ãã°è¯ã
ãŸããåéåã®ã¹ã³ã¢ãã©ã®ããã«å©çšããããAND ã«ããã OR ã«ããããšèšã£ã倿Žã®é㯠service ã¯ã©ã¹ã®ã¿ã®å€æŽã§æžã
ããã¯æ¬¡ï¿œï¿œï¿œã§è¿°ã¹ãããRedis ã«é¢ããæ§ã
ãªè©³çްå®è£
ãçç¥ã§ãã
ããã«ãããæ¬æ¥ã®ã¢ããªã±ãŒã·ã§ã³ã»ããžãã¯ã®ã¿ãèšè¿°ããã
ãã®ããã« RedBlocks ãé©åã«çšããŠå®è£
ããããšã§ãã¯ã©ã¹ããŒã¹ã®ãªããžã§ã¯ãæåããã°ã©ãã³ã°ã®æŠå¿µãå©çšããŠé©åã«é¢å¿ãåé¢ãã圢ã§ãäžèЧç»é¢ãå®è£
ã§ããããšãåãã£ãã
å®è£
ã«é¢ãã詳现
å
ã»ã©ã®ç« ã§ã¯ãRedBlocks ã䜿ãããšã§ Redis ᅵᅵᅵãªããžã§ã¯ãæåã®æ çµã¿ã§åãæ±ãããšãã§ããããšã説æããããã®ç« ã§ã¯ã課é¡2: å®è£
ã«å¿
èŠãªå€ãã®è©³çްãã«ã€ããŠãã詳ããè¿°ã¹ããå
·äœçã«ã©ã€ãã©ãªãè£ã§è¡ã£ãŠããä»äºã«ã€ããŠã以äžã®6ç¹ãåãäžããã
ããŒäœç³»
ãã£ãã·ã¥ãšããŠåäœããã
Redis äžã®ããŒã¿ã®çåæé
ãã£ãã·ã¥ãå·®åæŽæ°ã«ãã
空éåã衚çŸãã
éåã®æé©å
ããã§ã¯å®è£
äžã®è©³çްã«ã€ããŠåãäžãããããç¹ã«å
šäœãšããŠãŸãšãŸããããããã§ã¯ãªããèå³ã®ãã話é¡ã ããéžæçã«èŠãŠããããã°å¹žãã§ããã
ããŒäœç³»
Redis ãå©çšããã«ã¯åœç¶ããŒãæå®ããå¿
èŠãããããã ãããã®ããŒã«ã€ã㊠RedBlocks ã§ã¯æ¬¡ã®ãããªäœç³»ãçšããŠããïŒ
<å
šäœã®åå空é>:<ã¯ã©ã¹ã¬ãã«ã®èå¥å>:<ã€ã³ã¹ã¿ã³ã¹ã¬ãã«ã®èå¥å>
ãŸãããŒã3éå±€ã«åãããŠãããæåã®éå±€ã¯å
šäœã®åå空éã衚ããŠããŠãããã©ã«ãã§ "RB" ãšãªããäºã€ç®ã®éå±€ã¯ã¯ã©ã¹ã¬ãã«ã®èå¥åã衚ããŠããŠãRedBlocks::Set ãç¶æ¿ããã¯ã©ã¹ã®ååãããã©ã«ãã§å©çšããããäžã€ç®ã®éå±€ã¯ã€ã³ã¹ã¿ã³ã¹ã¬ãã«ã®èå¥åã衚ããŠããŠã䞻㫠key_suffix ã¡ãœããã®å®è£
ãéããŠããã°ã©ããæå®ãããäŸãã°ãå
ã»ã©åºãŠãããåæµ·éãå°åã«ããåéã®éåãæ¬¡ã®ãããªããŒãæ§ç¯ãããã
r = RegionSet.new('hokkaido') r.key #=> "RB:RegionSet:hokkaido"
åæåã®éåã®ããŒ
RedBlocks::UnionSet ãªã©åæåã®éåã®å Žåã¯ãkey_suffix ã®æ±ºå®ãèªåã§è¡ããã«ãŒã«ã¯ãå
å
ããå
šãŠã®éåã®ããŒããœãŒãã㊠| ã«ãã£ãŠçµåãããã®ãšãªãã
r1 = RegionSet.new('hokkaido') r2 = RegionSet.new('kanto') RedBlocks::UnionSet.new([r1, r2]).key_suffix #=> "[RB:RegionSet:hokkaido|RB:RegionSet:kanto]" RedBlocks::UnionSet.new([r1, r2]).key #=> "RB:RedBlocks::UnionSet:[RB:RegionSet:hokkaido|RB:RegionSet:kanto]"
ããã«ãã£ãŠãã«ã¹ã¿ã ã¯ã©ã¹ãå®çŸ©ããããšãªãç°¡åã«åéåãç©éåãšèšã£ãåæéåãäœãããšãã§ããŠããã
ãã£ãã·ã¥ãšããŠåäœããã
ãã£ãã·ã¥ãšããŠåäœããããã€ãŸããç¡ããã°å
ããŒã¿ãååŸããã£ãã·ã¥ã«ä¹ããŠæ¬¡å以éã¯ããã䜿ãããšããåäœãå®çŸããããã«ã次ã®ããã«ããŒã¿ååŸã®éã«ãã£ãã·ã¥ã®æç¡ããã§ãã¯ããŠããã
module RedBlocks class Set def disabled? RedBlocks.client.ttl(key) < RedBlocks.config.intermediate_set_lifetime # ãã® lifetime ã¯ããã©ã«ãã§30ç§ end def ids(...) update! if disabled? ... end end end
ãã®ã³ãŒãã¯ã該åœã®ã€ã³ã¹ã¿ã³ã¹ã«çžåœãã Redis ã® Sorted Set ã®çåæéããŸã 30ç§ä»¥äžããã°æå¹ã§ãããããã§ãªããã°ç¡å¹ãšå€å®ããŠããŒã¿ã®æŽæ°ãè¡ã£ãŠããïŒ0ã§ã¯ãªã30ç§ã§ããçç±ã¯æ¬¡ã§èª¬æããïŒã
Redis äžã®ããŒã¿ã®çåæé
RedBlocks ãéããŠå©çšãã Sorted Set ã¯ãã£ãã·ã¥ãšããŠäžå®æé Redis äžã«ååšãããããšãã§ãããããã®äžæ¹ã§ ZINTERSTORE(dest, src1, src2, ...) ã ZUNIONSTORE(dest, src1, src2, ...) ãšèšã£ãæŒç®ã Redis äžã§è¡ãããã«ã¯ããã£ãã·ã¥æéããŒãã«èšå®ãããŠããïŒã€ãŸãçµæãè¿ããçŽåŸã«æ¶æ»
ããŠè¯ãïŒ Sorted Set ã§ãã£ãŠãæäœéååšããªããã°ãªããªãæéãååšããã
RedBlocks ã§ã¯ãããããã©ã«ãã§30ç§ãšå®ãããïŒget ã¡ãœãããéããããŒã¿ã®ååŸãå«ããŠïŒids ãåŒã³åºããŠããæçµçµæååŸãŸã§ã®å
šãŠã®å·¥çšã30ç§ä»¥å
ã«çµäºããããšããä»®å®ã®å
ã«æ£åžžã«åäœããããšãä¿èšŒããŠããã
以äžã«ç€ºãå®è£
ã®éãããã£ãã·ã¥ãšããŠååšããæéãšã¯å¥ã§30ç§ã¯å¿
ãååšããããã«å
šãŠã®çåæéãèšå®ãããŠããã
module RedBlocks class Set def expiration_time RedBlocks.config.intermediate_set_lifetime + cache_time end def update! ... RedBlocks.client.expire(key, expiration_time) end end end
ãã£ãã·ã¥ãå·®åæŽæ°ã«ãã
ãã£ãã·ã¥ã®æŽæ°ã®éãäžåºŠå
šãŠãåé€ããŠããæ°ããããŒã¿ãå
¥ãããšããæ¹æ³ã ãšãç¬éçã«ãµãŒãã¹ã«ãããã³ã³ãã³ãã®ä»¶æ°ããŒãã«ãªã£ãŠããŸããäžç¬ã§ãã£ãŠããã®ç¶æ³ã¯å¥œãŸãããªããããå®éã®ãã£ãã·ã¥ã®æŽæ°åŠçã§ã¯æŽæ°ã®ååŸã§åé€ãããèŠçŽ ã®ã¿ãæç€ºçã« Sorted Set ããåãé€ããŠããïŒå¢åã«é¢ããŠã¯ã¹ã³ã¢ã®ã¿ãå€ããå¯èœæ§ããããããå
šãŠãæŽæ°ããå¿
èŠãããïŒã
module RedBlocks class Set def update! ... RedBlocks.client.pipelined do RedBlocks.client.zrem(key, removed_ids) if removed_ids.size > 0 RedBlocks.client.zadd(key, all_entries) RedBlocks.client.expire(key, expiration_time) end end end end
空éåã衚çŸãã
Redis ã® Sorted Set ã®ä»æ§ã§ã¯ãå
å
ããèŠçŽ ã0ä»¶ã§ãããšããç¶æ
ãšãSorted Set èªäœãååšããªããšããç¶æ
ãåºå¥ã§ããªããããããRedBlocks ã®ãŠãŒã¹ã±ãŒã¹ã«ãããŠã¯ãã空ã®éåã§ããããšããç¶æ
ããã£ãã·ã¥ãããïŒäŸãã°ãç¹å®ã®ããŒã¯ãŒãã«ããå
šææ€çŽ¢ã®çµæã0ã§ãããšããããšèªäœããã£ãã·ã¥ãããïŒã
ãã®ãããå®éã«ã³ã³ãã³ãã«å¯Ÿå¿ããèŠçŽ ä»¥å€ã«ãid ã 0 ã®èŠçŽ ãåžžã«å ããããã«ãªã£ãŠããããã® 0 ã¯å®åšããèŠçŽ ã® id ãšããŠåãåŸãªãå€ãæ³å®ããŠãããRedBlocks.config.blank_id ãéããŠå¥ã®å€ã«ãèšå®ããããšãã§ããã
éåã®æé©å
æåŸã«ãéåæ§é ãæé©åãã RedBlocks::Set#unset ã«ã€ããŠç޹ä»ããã
ç¶æ³ãšããŠããè·çš®ããšãå°åããšèšã£ãè€æ°ã®èгç¹ã§ã®çµã蟌ã¿ãã§ãã仿§ããããšãããäŸãã°ã次ã®ãããªã¯ãšãªãããåŸãïŒ
# pattern 1 ([ãšã³ãžãã¢ã®åé] ⪠[ãã¶ã€ããŒã®åé]) â© ([åæµ·éã®åé] ⪠[颿±ã®åé] ⪠[æ±æµ·ã®åé]) // pattern 2 [ãã¶ã€ããŒã®åé] â© [åæµ·éã®åé]
ãã®ãšããäž¡è
ãåæã«åŠçã§ããããã«äžè¬çãªããã°ã©ã ãæžããšãåŸè
ã¯æ¬¡ã®ãããªæ§é ã«ãªãå¯èœæ§ãé«ãã
pattern1_set = RedBlocks::IntersectionSet.new(RedBlocks::UnionSet.new([engineer_set, designer_set]), RedBlocks::UnionSet.new([hokkaido_set, kanto_set, tokai_set])) pattern2_set = RedBlocks::IntersectionSet.new(RedBlocks::UnionSet.new([engineer_set]), RedBlocks::UnionSet.new([hokkaido_set]))
åœç¶ãªãããã®éåæ§é ã¯åé·ã§ãããæåã«ç€ºãããããªã¯ãšãªã«å€æã§ãããšè¯ãã圢åŒçã«èšã£ãŠå
éšã«1ã€ã®éåãæã€ãããªç©éåã¯ãã®å
éšã®éåãšç䟡ã§ããããããã®ãããªåé·ãªæ§é ãååž°çã«æé©åããããã« unset ã¡ãœãããçšæããŠããããã®äŸã§ã¯ã以äžã®ããã«åäœããã
pattern2_set.unset #=> RedBlocks::IntersectionSet.new(engineer_set, hokkaido_set)
å¶éäºé
以äžããã®ç¯ã§ç޹ä»ããå®è£
詳现ã®ãã¡ã次ã®äºã€ã®ã¢ã€ãã¢ã«ã€ããŠå¶éäºé
ãæ€èšããã
Redis ãæŒç®ãšãã£ãã·ã¥ã®äºã€ã®ç®çã§å©çš
Redis ã®ããŒã®èªåçæ
1 ã«ããåçŽãªã·ã¹ãã æ§æã«ãªãã2ã«ããããã°ã©ãã³ã°äžã®äºäºãæ¶å€±ããã ãããã¯ã€ãã¯ã«äœã¬ã€ãã³ã·ãŒãªæ€çŽ¢ã»ãã£ã«ã¿ãªã³ã°ã·ã¹ãã ãæ§ç¯ããããšã«å¯äžããã ããããªãããããã€ãã®ç¶æ³ã«ãããŠã¯ãã®ã¢ãããŒãã¯é©ããªããšæãããã
ãŸã1ã«ã€ããŠã¯ãRedis äžã§ã®æŒç®ãåæãšããŠãããããæŒç®æ§èœããŸã Redis ã®äžéã«å¶çŽããããããã¯æ°åäžä»¶çšåºŠã®ããŒã¿ã察象ã§ãã°åé¡ã«ãªããªãããæ°åäžä»¶ä»¥äžã®ããŒã¿ãããå Žåã¯æ§èœäžã®åé¡ãåºãããã®ãããªèŠæš¡ã«æé·ããå Žåã¯ãæŒç®ã®è²¬åã Redis ã«æ
ãããã®ã§ã¯ãªãå¥ã®ã·ã¹ãã ã«æ
ãããã®ã劥åœã ããã
次ã«2ã«ã€ããŠã¯ãã¯ã©ã¹åãšããããã°ã©ã äžã®å®äœããããŒãçæããŠãããããããã®å€æŽã«åœ±é¿ãåãããããããã£ãã·ã¥ã® Thundering Herd ãåŒãèµ·ããå¯èœæ§ãåççã«ååšããããã®ãããªéåžžã«é«äžŠåæ§ã®ã·ã¹ãã ã«ãããŠã¯ãæŒç®ããªã³ã©ã€ã³ã§è¡ãã®ã§ã¯ãªãããªãã©ã€ã³ã§è¡ã£ãŠãããªã©ãç°ãªãã¢ãããŒããæ€èšããã¹ãã ãšæãããã
ãããã«
æ¬çš¿ã§ã¯ãRedis ã® Sorted Set ã® Web ãµãŒãã¹ã«ãããæŽ»ç𿹿³ãšããŠãäžèЧç»é¢ã®å®è£
ã§ã®å©çšãæãããç¹ã«ããã€ã¯ããµãŒãã¹æèã§ã¯è€æ°ã®ã·ã¹ãã ã®ãçµ±åãã«èª²é¡ãããããšãææãããã®åºå¹¹éšåã« Redis ã® Sorted Set ã䜿ãããšãææ¡ããã
ãã®äžã§ããããçŸå®çã«ä¿å®å¯èœãªåœ¢ã§å®è£
ããããã« RedBlocks ãšããæœè±¡åãè¡ããå®éã®ã¢ããªã±ãŒã·ã§ã³ã§æ±ãããã仿§ãããã¯ã¢ããããªãããããäžæãèšè¿°ã§ããããšã®ã±ãŒã¹ã¹ã¿ãã£ãè¡ã£ãããã®ã±ãŒã¹ã¹ã¿ãã£ã®äžã§ã¯ãHTTP ãµãŒããŒã§ã¯ãªã ActiveRecord ãä»ããŠããŒã¿ããŒã¹ãžåãåããããããªãµã³ãã«ã³ãŒããæ²èŒããŠãããããã€ã¯ããµãŒãã¹ã®ç§»è¡æã«ã¯ HTTP ã«ããéä¿¡ãšããŒã¿ããŒã¹ãžã®çŽæ¥åç
§ãæ··åããã±ãŒã¹ãå€ãããããã£ãéšåãå«ããŠçŸå®çã«äœ¿ã£ãŠããçµ±åææ³ãšããŠç޹ä»ããã
ãŸããRedBlocks ã«ã€ããŠã¯æŽã«èžã¿èŸŒãã§ãã¢ããªã±ãŒã·ã§ã³ã®ããžãã¯ãå®çµã«èšè¿°ã§ããããã«ããããã«è£ã«ã©ã®ãããªä»äºãé èœããå¿
èŠããã£ããã玹ä»ãããç¹ã«ãè€é㪠Redis ã®ããŒã¿æ§é ãã©ã®ããã«ã¯ã©ã¹ããŒã¹ã®ãªããžã§ã¯ãæåããã°ã©ãã³ã°ã«èœãšã蟌ããããããšé¢é£ããŠã©ã®ããã«ã·ã¹ããããã¯ã«ããŒã管çããããšãããããªãããã¯ã¯ãä»ã® Redis ã®ããŒã¿åã«å¯ŸããŠãé©çšã§ããå¯èœæ§ããããä»åŸã®çºå±ãèŠèŸŒããã
0 notes
Text
Keep your pet safe with a custom engraved dog collar from CurliTail. Made in the USA, stylish, and built to last.
#dog collar#dogcollarbow#floralflowercollars#dogharness#leashset#personalizedset#dogcollar#flowercollars#curlitail
0 notes
Text
Discover premium personalized leather dog collars at CurliTail. Durable, stylish, and custom-engraved for your petâs comfort and safety. Shop now! https://curlitail.com/
0 notes
Text
Explore our premium floral flower collars, designed for comfort and beauty. Perfect for dogs and cats. Find your petâs new look today!
#curlitail#dog collar#dogcollar#dogharness#dogcollarbow#floralflowercollars#flowercollars#leashset#personalizedset#girldogcollar
0 notes
Text

Get a customized dog collar & leash set with your petâs name & details. Stylish, durable, & comfortableâshop the best personalized sets at CurliTail! Visit https://curlitail.com/
#curlitail#dog collar#dogcollarbow#dogharness#floralflowercollars#leashset#personalizedset#flowercollars#dogcollar#girldogcollar
0 notes
Text
Get the best-personalized dog mom-dad sweatshirts & t-shirts in the USA. Soft, stylish, and made with loveâperfect for proud pet parents!
#dog collar#dogcollarbow#curlitail#flowercollars#floralflowercollars#leashset#personalizedset#dogharness#dogcollar#girldogcollar
0 notes
Text
Top 5 Benefits of Personalized Dog ID Collars and Leashes for Your Furry Friend
Every pet owner wants to ensure their furry friend is safe, comfortable, and stylish. Personalized dog ID collars and leashes are a great way to achieve this while providing essential identification in case your pet gets lost. Here are the top five benefits of investing in a customized collar and leash for your dog.
Enhanced Safety and Quick Identification
One of the most significant advantages of a personalized dog ID collar is the immediate identification it provides. If your dog ever wanders away, a collar with their name and your contact information makes it easier for someone to return them quickly. Unlike ID tags that can fall off or fade over time, personalized collars keep essential details securely in place.
Stylish and Unique Design
Custom collars and leashes allow pet owners to showcase their dog's personality. Whether you prefer a sleek, elegant design or something colorful and fun, you can choose fonts, colors, and materials that reflect your petâs unique style. Personalized options also make it easy to distinguish your dogâs accessories from others at the park or doggy daycare.
Comfort and Durability
Many personalized dog ID collars and leashes are made from high-quality materials such as nylon, leather, or waterproof fabric, ensuring durability and long-lasting comfort. Adjustable sizes and soft linings help prevent chafing, making them comfortable for daily wear. Investing in a high-quality custom collar means less frequent replacements and better security for your pet.
Helps in Emergency Situations
In case of an emergency, a personalized collar can provide crucial information. Some pet owners include additional details like medical conditions, allergies, or special needs on their dogâs collar. This ensures that if your pet is found by someone else, they are aware of any health concerns that require immediate attention.
Conclusion
Personalized dog ID collars and leashes are more than just stylish accessoriesâthey are essential tools that enhance your pet's safety, comfort, and identity. With benefits ranging from quick identification to durability and unique designs, investing in a customized collar and leash is a smart decision for any pet owner. Give your furry friend the protection they deserve while adding a touch of personality to their daily walks!
0 notes
Text

Pamper your pet with Personalized navy velvet dog bed. Stylish, cozy, and personalized for your dogâs comfort. Made in the USA. Visit https://curlitail.com/
0 notes
Photo

Pretty in Pink Knit Choker âšShop Wild Childâš Link in Bioâ â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â #WildChildCreations #knitchoker #chokernecklace #spookycute #spookyjewlery #modernpinup #creepyshop #alternativegirl #softgoth #Cutekawaii #stayspooky #giftsforfriends #pinupgirl #personalizeditems #personalizedkeychain #kawaiiaesthetic #personalizedgifts #pastelgoth #kawaiistyle #pinkaesthetic #kawaiiaccessories #custommade #spookystyle #witchyaesthetic #prettyinpinkblush #personalizedset #cottagecore #smallshoplove #prettyinparisian #womenownedsmallbusiness https://www.instagram.com/p/CJ6dfv6gWex/?igshid=1b2c0661di3cc
#wildchildcreations#knitchoker#chokernecklace#spookycute#spookyjewlery#modernpinup#creepyshop#alternativegirl#softgoth#cutekawaii#stayspooky#giftsforfriends#pinupgirl#personalizeditems#personalizedkeychain#kawaiiaesthetic#personalizedgifts#pastelgoth#kawaiistyle#pinkaesthetic#kawaiiaccessories#custommade#spookystyle#witchyaesthetic#prettyinpinkblush#personalizedset#cottagecore#smallshoplove#prettyinparisian#womenownedsmallbusiness
0 notes
Photo

No one can stop you from trying âšShop Wild Childâš Link in Bioâ â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â #WildChildCreations #staymotivated #strongwomen #spookycute #spookyjewlery #modernpinup #creepyshop #alternativegirl #softgoth #Cutekawaii #stayspooky #giftsforfriends #pinupgirl #personalizeditems #personalizedkeychain #kawaiiaesthetic #personalizedgifts #pastelgoth #kawaiistyle #pinkaesthetic #kawaiiaccessories #custommade #spookystyle #witchyaesthetic #losangeles #personalizedset #kindnessmatters #smallshoplove #newyearnewgoals #womenownedsmallbusiness (at Los Angeles, California) https://www.instagram.com/p/CJZH_u3ARzv/?igshid=bfiuxstxrxl6
#wildchildcreations#staymotivated#strongwomen#spookycute#spookyjewlery#modernpinup#creepyshop#alternativegirl#softgoth#cutekawaii#stayspooky#giftsforfriends#pinupgirl#personalizeditems#personalizedkeychain#kawaiiaesthetic#personalizedgifts#pastelgoth#kawaiistyle#pinkaesthetic#kawaiiaccessories#custommade#spookystyle#witchyaesthetic#losangeles#personalizedset#kindnessmatters#smallshoplove#newyearnewgoals#womenownedsmallbusiness
0 notes
Photo

Rose Hoop Earrings ð¹ Available in Shop now ð€ âšShop Wild Childâš Link in Bioâ â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â .â â â â â â â â â â â â â â â â â â â â â â â â #WildChildCreations #roseearrings #spookycute #spookyjewlery #modernpinup #hoopearrings #alternativegirl #halloweeniseveryday #softgoth #Cutekawaii #stayspooky #giftsforfriends #pinupgirl #personalizeditems #personalizedkeychain #kawaiiaesthetic #personalizedgifts #pastelgoth #kawaiistyle #pinkaesthetic #kawaiiaccessories #custommade #spookystyle #witchyaesthetic #animevibes #personalizedset #latinavibes #roseacccesaories #shopsmallbusinesses #rosejewlery (at Los Angeles, California) https://www.instagram.com/p/CJWTbdagKZf/?igshid=5ggvq0bkb705
#wildchildcreations#roseearrings#spookycute#spookyjewlery#modernpinup#hoopearrings#alternativegirl#halloweeniseveryday#softgoth#cutekawaii#stayspooky#giftsforfriends#pinupgirl#personalizeditems#personalizedkeychain#kawaiiaesthetic#personalizedgifts#pastelgoth#kawaiistyle#pinkaesthetic#kawaiiaccessories#custommade#spookystyle#witchyaesthetic#animevibes#personalizedset#latinavibes#roseacccesaories#shopsmallbusinesses#rosejewlery
0 notes