Redis का उपयोग करके पैटर्न से मेल खाते कुंजी को एटमेटिक रूप से कैसे हटाएं


575

मेरे रेडिस डीबी में मेरे पास कई prefix:<numeric_id>हैश हैं।

कभी-कभी मैं उन सभी को परमाणु रूप से शुद्ध करना चाहता हूं। कुछ वितरित लॉकिंग तंत्र का उपयोग किए बिना मैं यह कैसे करूं?


हाय स्टीव, मेरी वेबसाइट के साथ कुछ समस्या है, मैंने इसे अपने अन्य ब्लॉग mind-geek.net/nosql/redis/delete-keys-specific-expiry-time पर जोड़ा है , आशा है कि यह मदद करता है।
गौरव तिवारी

43
यह एक ऐसा सामान्य परिदृश्य है जो मैं चाहता हूं कि रेडिस टीम इसके लिए एक देशी कमांड जोड़ने पर विचार करे।
टोड मेनियर

आजकल आप बस लुआ के साथ ऐसा कर सकते हैं, नीचे देखें।
अलेक्जेंडर ग्लैडिस

3
@ToddMenier ने बस सुझाव दिया, इस तर्क को वापस लिया कि ऐसा क्यों नहीं होगा: github.com/antirez/redis/issues/2042
रे

1
बहुत से लोग संबंधित प्रश्न पूछ रहे हैं कि बड़ी संख्या में चाबियों को कैसे संभालना है, विशेष वर्णों के साथ चाबियाँ, आदि। मैंने एक अलग प्रश्न बनाया है क्योंकि हम अब इस समस्या को उठा रहे हैं और मुझे नहीं लगता कि इस प्रश्न पर उत्तर पोस्ट किया गया है। यहाँ अन्य प्रश्न है: stackoverflow.com/questions/32890648/…
jakejgordon

जवाबों:


431

रेडिस 2.6.0 से शुरू होकर, आप लुआ स्क्रिप्ट चला सकते हैं, जो परमाणु रूप से निष्पादित होती है। मैंने कभी एक नहीं लिखा है, लेकिन मुझे लगता है कि यह कुछ इस तरह दिखाई देगा

EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 prefix:[YOUR_PREFIX e.g delete_me_*]

चेतावनी : जैसा कि रेडिस दस्तावेज़ कहता है, प्रदर्शन मैटर्स के कारण, keys कमांड को उत्पादन में नियमित संचालन के लिए उपयोग नहीं करना चाहिए, यह कमांड डीबगिंग और विशेष संचालन के लिए है। अधिक पढ़ें

EVAL दस्तावेज़ देखें ।


23
महत्वपूर्ण नोट: यदि आप उपसर्ग से मेल खाते दो हज़ार से अधिक कुंजी रखते हैं तो यह विफल हो जाता है।
नाथन उस्मान

93
यह एक बड़ी संख्या के लिए काम कर रहा है:EVAL "local keys = redis.call('keys', ARGV[1]) \n for i=1,#keys,5000 do \n redis.call('del', unpack(keys, i, math.min(i+4999, #keys))) \n end \n return keys" 0 prefix:*
sheerun

181
आउच ... रेडिस का उपयोग साधारण कुंजी / स्टोर कैश के रूप में किया जाता है। ऐसा लगता है del prefix:* कि एक मौलिक ऑपरेशन होना चाहिए: /
रे

5
@Ray स्पष्ट रूप से, अगर आप उस सुविधा की जरूरत है तो आप बस numetic डेटाबेस या सर्वर, और उपयोग फ्लश / flushdb से डेटा विभाजन चाहिए
मार्क Gravell

9
यदि कोई कुंजी मिलान पैटर्न नहीं है तो यह विफल रहता है। यह तय करने के लिए कि मैंने एक डिफ़ॉल्ट कुंजी जोड़ी है:EVAL "return redis.call('del', 'defaultKey', unpack(redis.call('keys', ARGV[1])))" 0 prefix:*
manuelmhtr

706

बाश में निष्पादित करें:

redis-cli KEYS "prefix:*" | xargs redis-cli DEL

अपडेट करें

ठीक हैं मैं समझ गया। इस तरह के बारे में क्या: वर्तमान अतिरिक्त वृद्धिशील उपसर्ग को संग्रहीत करें और इसे अपनी सभी कुंजियों में जोड़ें। उदाहरण के लिए:

आपके पास इस तरह के मान हैं:

prefix_prefix_actuall = 2
prefix:2:1 = 4
prefix:2:2 = 10

जब आपको डेटा शुद्ध करने की आवश्यकता होती है, तो आप पहले प्रीफ़िक्स_एक्ट्यूएल बदलते हैं (उदाहरण के लिए सेट प्रीफ़िक्स_प्रिफ़िक्स_एक्टुआल = 3), इसलिए आपका एप्लिकेशन कुंजी उपसर्ग: 3: 1 और उपसर्ग: 3: 2 में नया डेटा लिखेगा। फिर आप उपसर्ग: 2: 1 और उपसर्ग: 2: 2 से पुराने मान सुरक्षित रूप से ले सकते हैं और पुरानी कुंजियों को शुद्ध कर सकते हैं।


14
क्षमा करें, लेकिन यह परमाणु विलोपन नहीं है। कोई व्यक्ति कुंजी और DEL के बीच नई कुंजी जोड़ सकता है। मैं उन्हें हटाना नहीं चाहता।
अलेक्जेंडर ग्लैडीश

36
कुंजियाँ, जो KEYS कमांड डिलीट नहीं होने के बाद बनाई जाएंगी।
केसी

6
मुझे बस कुछ खराब कुंजियों को साफ करने की आवश्यकता थी, इसलिए केसी का पहला उत्तर हाजिर था, सिवाय इसके कि मुझे कोट्स के बाहर कीज़ को स्थानांतरित करना था: redis-cli KEYS "उपसर्ग: *" | xargs redis-cli DEL
jslatts

19
पहले उत्तर ने भी मेरी मदद की। एक और प्रकार यदि आपके redis कुंजी उद्धरण या अन्य वर्ण हो xargs अप गड़बड़ है कि:redis-cli KEYS "prefix:*" | xargs --delim='\n' redis-cli DEL
overthink

18
यदि आपके पास बहुपयोगी डेटाबेस (कीस्पेसेस) हैं तो यह चाल है: चलिए बताते हैं कि आपको db3 में कुंजियाँ हटाने की आवश्यकता है:redis-cli -n 3 KEYS "prefix:*" | xargs redis-cli -n 3 DEL
Christoffer

73

यहां लुआ में लागू वाइल्डकार्ड डिलीट का पूरी तरह से काम और परमाणु संस्करण है। यह बहुत ही कम नेटवर्क के पीछे और आगे xargs संस्करण की तुलना में बहुत तेज़ी से चलेगा, और यह पूरी तरह से परमाणु है, जब तक यह खत्म नहीं होता तब तक रेडिस के खिलाफ किसी भी अन्य अनुरोध को अवरुद्ध करता है। यदि आप Redis 2.6.0 या उससे अधिक की एटमॉली को हटाना चाहते हैं, तो यह निश्चित रूप से जाने का तरीका है:

redis-cli -n [some_db] -h [some_host_name] EVAL "return redis.call('DEL', unpack(redis.call('KEYS', ARGV[1] .. '*')))" 0 prefix:

यह इस प्रश्न के उत्तर में @ mcdizzle के विचार का एक कार्यशील संस्करण है। विचार का श्रेय 100% उसे जाता है।

संपादित करें: प्रति किकोइटो की टिप्पणी के अनुसार, यदि आपके पास अपने रेडिस सर्वर में मुफ्त मेमोरी से हटाने के लिए अधिक कुंजी है, तो आप "बहुत सारे तत्वों को अनपैक करने के लिए" त्रुटि में चलेंगे । उस मामले में, करें:

for _,k in ipairs(redis.call('keys', ARGV[1])) do 
    redis.call('del', k) 
end

जैसा कि किकिटो ने सुझाव दिया था।


10
उपरोक्त कोड टैंक होगा यदि आपके पास महत्वपूर्ण संख्या है (त्रुटि "अनपैक करने के लिए बहुत सारे तत्व हैं")। मैं लुआ भाग पर एक लूप का उपयोग करने की सलाह देता हूं:for _,k in ipairs(redis.call('keys', KEYS[1])) do redis.call('del', k) end
किकिटो

@kikito, हां, अगर लुआ उस ढेर की चाबी नहीं जुटा सकता है जिसे आप हटाना चाहते हैं (स्मृति की कमी के कारण सबसे अधिक संभावना है), तो आपको इसे लूप के लिए करना होगा। मैं आपको ऐसा करने की सलाह नहीं दूंगा जब तक आपको नहीं करना है।
एलि

1
लुआ unpackएक तालिका को "स्वतंत्र चर की सूची" में बदल देता है (अन्य भाषाएं कहती हैं कि explode) लेकिन अधिकतम संख्या सिस्ट मेमोरी पर निर्भर नहीं है; यह स्थिर के माध्यम से लुआ में तय हो गया LUAI_MAXSTACKहै। Lua 5.1 और LuaJIT में यह 8000 है और Lua 5.2 में 100000 है। लूप विकल्प के लिए IMO की सिफारिश की गई है।
किकिटो

1
यह ध्यान देने योग्य है कि लुआ स्क्रिप्टिंग केवल
रेडिस

1
कोई भी लुआ-आधारित समाधान अर्थविद्या का उल्लंघन करेगा EVALक्योंकि यह उन कुंजियों को पहले से निर्दिष्ट नहीं करता है जिन पर यह काम करेगा। इसे एक ही उदाहरण पर काम करना चाहिए, लेकिन यह उम्मीद न करें कि यह रेडिस क्लस्टर के साथ काम करेगा।
केविन क्रिस्टोफर हेनरी

66

अस्वीकरण: निम्नलिखित समाधान परमाणुता प्रदान नहीं करता है

V2.8 से शुरू करके आप वास्तव में KEYS [1] के बजाय SCAN कमांड का उपयोग करना चाहते हैं । निम्नलिखित बैश स्क्रिप्ट पैटर्न द्वारा कुंजियों को हटाने का प्रदर्शन करती है:

#!/bin/bash

if [ $# -ne 3 ] 
then
  echo "Delete keys from Redis matching a pattern using SCAN & DEL"
  echo "Usage: $0 <host> <port> <pattern>"
  exit 1
fi

cursor=-1
keys=""

while [ $cursor -ne 0 ]; do
  if [ $cursor -eq -1 ]
  then
    cursor=0
  fi

  reply=`redis-cli -h $1 -p $2 SCAN $cursor MATCH $3`
  cursor=`expr "$reply" : '\([0-9]*[0-9 ]\)'`
  keys=${reply##[0-9]*[0-9 ]}
  redis-cli -h $1 -p $2 DEL $keys
done

[१] KEYS एक खतरनाक कमांड है जो संभावित रूप से DoS में परिणाम कर सकता है। निम्नलिखित इसके प्रलेखन पृष्ठ से एक उद्धरण है:

चेतावनी: कुंजी को एक कमांड के रूप में माना जाता है जिसे केवल अत्यधिक सावधानी के साथ उत्पादन वातावरण में उपयोग किया जाना चाहिए। बड़े डेटाबेस के खिलाफ निष्पादित होने पर यह प्रदर्शन को बर्बाद कर सकता है। यह कमांड डीबगिंग और विशेष परिचालनों के लिए है, जैसे कि आपका कीस्पेस लेआउट बदलना। अपने नियमित एप्लिकेशन कोड में कुंजियों का उपयोग न करें। यदि आप अपने कुंजी क्षेत्र के सबसेट में कुंजियाँ खोजने का तरीका खोज रहे हैं, तो सेट का उपयोग करने पर विचार करें।

अद्यतन: एक ही मूल प्रभाव के लिए एक लाइनर -

$ redis-cli --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli DEL

9
फिर भी, कुंजी से बचना निश्चित रूप से सबसे अच्छा अभ्यास माना जाता है, इसलिए यह एक महान समाधान है जहां गैर-परमाणु विलोपन संभव हैं।
२०:५० पर fatal_error

इसने मेरे लिए काम किया; हालाँकि, मेरी चाबियाँ डेटाबेस 1 में हुईं। इसलिए मुझे -n 1प्रत्येक redis-cliआह्वान में शामिल होना था:redis-cli -n 1 --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli -n 1 DEL
रोब जोहान्स

ध्यान दें कि यह काम नहीं करता है यदि आपकी कुंजियों में विशेष वर्ण हैं
mr1031011

दिलचस्प और मूल्यवान खोज ... मुझे आश्चर्य है कि अगर xargs के लिए चीजों को उद्धृत करने का एक तरीका है ...
इटमार हैबर

-L 100 क्या करता है ??
अपर्णा

41

उन लोगों के लिए जिन्हें अन्य उत्तर देने में समस्या हो रही थी:

eval "for _,k in ipairs(redis.call('keys','key:*:pattern')) do redis.call('del',k) end" 0

key:*:patternअपने खुद के पैटर्न के साथ बदलें और इसे दर्ज करें redis-cliऔर आप जाने के लिए अच्छे हैं।

क्रेडिट लिस्को से: http://redis.io/commands/del


37

मैं रेडिस 3.2.8 में नीचे कमांड का उपयोग कर रहा हूं

redis-cli KEYS *YOUR_KEY_PREFIX* | xargs redis-cli DEL

आप यहाँ से कीज़ पैटर्न सर्च से संबंधित अधिक सहायता प्राप्त कर सकते हैं: - https://redis.io/commands/keys । अपनी आवश्यकता के अनुसार अपनी सुविधाजनक ग्लोब स्टाइल पैटर्न का उपयोग करें *YOUR_KEY_PREFIX*या जैसेYOUR_KEY_PREFIX?? या किसी अन्य।

और यदि आप में से किसी ने भी Redis PHP लाइब्रेरी को एकीकृत किया है तो नीचे दिए गए फंक्शन से आपको मदद मिलेगी।

flushRedisMultipleHashKeyUsingPattern("*YOUR_KEY_PATTERN*"); //function call

function flushRedisMultipleHashKeyUsingPattern($pattern='')
        {
            if($pattern==''){
                return true;
            }

            $redisObj = $this->redis;
            $getHashes = $redisObj->keys($pattern);
            if(!empty($getHashes)){
                $response = call_user_func_array(array(&$redisObj, 'del'), $getHashes); //setting all keys as parameter of "del" function. Using this we can achieve $redisObj->del("key1","key2);
            }
        }

धन्यवाद :)


23

@ mcdizle का समाधान काम नहीं कर रहा है यह केवल एक प्रविष्टि के लिए काम करता है।

यह एक ही उपसर्ग के साथ सभी कुंजी के लिए काम करता है

EVAL "for i, name in ipairs(redis.call('KEYS', ARGV[1])) do redis.call('DEL', name); end" 0 prefix*

नोट: आपको अपने प्रमुख उपसर्ग के साथ 'उपसर्ग' को बदलना चाहिए ...


2
10 ^ 4 के क्रम में xua का उपयोग करने की तुलना में लू का उपयोग तेजी से कम हो रहा है।
गहरा

22

कुंजी को हटाने के लिए आप इस कमांड का उपयोग कर सकते हैं: -

मान लीजिए कि आपकी लालियों में कई तरह की चाबियां हैं-

  1. 'Xyz_category_fpc_12'
  2. 'Xyz_category_fpc_245'
  3. 'Xyz_category_fpc_321'
  4. 'Xyz_product_fpc_876'
  5. 'Xyz_product_fpc_302'
  6. 'Xyz_product_fpc_01232'

पूर्व- ' xyz_category_fpc ' यहाँ xyz एक है sitename , और इन कुंजियों उत्पादों और एक ई-कॉमर्स साइट के श्रेणियों से संबंधित और पांचवें वेतन आयोग द्वारा उत्पन्न कर रहे हैं।

यदि आप इस आदेश का उपयोग नीचे के रूप में करते हैं-

redis-cli --scan --pattern 'key*' | xargs redis-cli del

या

redis-cli --scan --pattern 'xyz_category_fpc*' | xargs redis-cli del

यह ' xyz_category_fpc ' (1, 2 और 3 कुंजी हटाएं) जैसी सभी कुंजी को हटा देता है । अन्य 4, 5 और 6 नंबर कुंजियों को हटाने के लिए ' xyz_product_fpc ' का उपयोग करें के लिए उपरोक्त कमांड में ' का ।

यदि आप Redis में सब कुछ हटाना चाहते हैं , तो इन कमांड का पालन करें-

रेडिस-क्ली के साथ:

  1. FLUSHDB - आपके कनेक्शन के CURRENT डेटाबेस से डेटा हटाता है।
  2. FLUSHALL - सभी डेटाबेस से डेटा निकालता है।

उदाहरण के लिए: - अपने शेल में:

redis-cli flushall
redis-cli flushdb

3
धन्यवाद, लेकिन पाइपिंग आउटपुट redis-cli delपरमाणु नहीं है।
अलेक्जेंडर ग्लैडीश

13

यदि आपके पास कुंजियों के नाम पर जगह है, तो आप इसे bash में उपयोग कर सकते हैं:

redis-cli keys "pattern: *" | xargs -L1 -I '$' echo '"$"' | xargs redis-cli del

10

@ इटमार का उत्तर बहुत अच्छा है, लेकिन उत्तर की पार्सिंग मेरे लिए नहीं जासूसी का काम कर रही थी। उस स्थिति में जहां दिए गए स्कैन में कोई कुंजी नहीं मिली है। संभवतः कंसोल से सीधे एक सरल समाधान,

redis-cli -h HOST -p PORT  --scan --pattern "prefix:*" | xargs -n 100 redis-cli DEL

यह SCAN का भी उपयोग करता है, जो उत्पादन में कुंजी के लिए बेहतर है, लेकिन परमाणु नहीं है।


8

मुझे बस यही समस्या थी। मैंने प्रारूप में उपयोगकर्ता के लिए सत्र डेटा संग्रहीत किया है:

session:sessionid:key-x - value of x
session:sessionid:key-y - value of y
session:sessionid:key-z - value of z

इसलिए, प्रत्येक प्रविष्टि एक अलग कुंजी-मूल्य जोड़ी थी। जब सत्र नष्ट हो जाता है, तो मैं पैटर्न के साथ चाबियाँ हटाकर सभी सत्र डेटा को निकालना चाहता था session:sessionid:*- लेकिन रेडिस में ऐसा कोई फ़ंक्शन नहीं है।

मैंने क्या किया: एक हैश के भीतर सत्र डेटा संग्रहीत करें । मैं बस के हैश आईडी के साथ एक हैश बनाने session:sessionidऔर उसके बाद मैं धक्का key-x, key-y, key-zकि हैश में (आदेश नहीं बात मेरे लिए किया था) और अगर मैं जरूरत है कि हैश अब मैं सिर्फ एक ऐसा न DEL session:sessionidऔर उस हैश आईडी से संबद्ध सभी डेटा चला गया है। DELपरमाणु और अभिगम डेटा / हैश को डेटा लिखना हे (1) है।


अच्छा समाधान है, लेकिन मेरे मूल्य खुद को राख कर रहे हैं। और रेडिस स्टोर हैश के अंदर एक और हैश।
अलेक्जेंडर ग्लैडीश

3
हालांकि, हैश के भीतर के क्षेत्रों में एक्सपायर कार्यक्षमता की कमी होती है, जो कभी-कभी वास्तव में उपयोगी होती है।
इवि सांग

मेरे लिए यह अब तक का सबसे साफ / सरल उत्तर है
सेबस्टियन एच।

क्या कोई सेट ज्यादा मायने नहीं रखता है?
जैक टक

5

मुझे लगता है कि MULTI / EXEC / DISCARD क्या आपकी मदद कर सकता है । लेन-देन के 100% समतुल्य नहीं होने पर, आपको डिलीट को अन्य अपडेट से अलग करने में सक्षम होना चाहिए।


4
लेकिन मैं यह पता नहीं लगा सकता कि उन्हें यहाँ कैसे इस्तेमाल करना है। DEL खुद से परमाणु है (या तो मुझे लगता है)। और जब तक मैं EXEC नहीं करता तब तक मुझे KEYS से मान नहीं मिल सकते, इसलिए मैं उसी MULTI में KEYS और DEL का उपयोग नहीं कर सकता।
अलेक्जेंडर ग्लैडिश

5

FYI करें।

  • केवल बैश और का उपयोग कर redis-cli
  • उपयोग नहीं keys(यह उपयोग करता है scan)
  • क्लस्टर मोड में अच्छी तरह से काम करता है
  • परमाणु नहीं

हो सकता है कि आपको केवल पूंजी पात्रों को संशोधित करने की आवश्यकता हो।

scan-match.sh

#!/bin/bash
rcli=“/YOUR_PATH/redis-cli" 
default_server="YOUR_SERVER"
default_port="YOUR_PORT"
servers=`$rcli -h $default_server -p $default_port cluster nodes | grep master | awk '{print $2}' | sed 's/:.*//'`
if [ x"$1" == "x" ]; then 
    startswith="DEFAULT_PATTERN"
else
    startswith="$1"
fi
MAX_BUFFER_SIZE=1000
for server in $servers; do 
    cursor=0
    while 
        r=`$rcli -h $server -p $default_port scan $cursor match "$startswith*" count $MAX_BUFFER_SIZE `
        cursor=`echo $r | cut -f 1 -d' '`
        nf=`echo $r | awk '{print NF}'`
        if [ $nf -gt 1 ]; then
            for x in `echo $r | cut -f 1 -d' ' --complement`; do 
                echo $x
            done
        fi
        (( cursor != 0 ))
    do
        :
    done
done

clear-redis-key.sh

#!/bin/bash
STARTSWITH="$1"

RCLI=YOUR_PATH/redis-cli
HOST=YOUR_HOST
PORT=6379
RCMD="$RCLI -h $HOST -p $PORT -c "

./scan-match.sh $STARTSWITH | while read -r KEY ; do
    $RCMD del $KEY 
done

बैश प्रॉम्प्ट पर चलाएं

$ ./clear-redis-key.sh key_head_pattern

5

Guide$CLASSMETADATA][1]उदाहरण के लिए, यदि आपकी कुंजी में विशेष वर्ण हैं, तो अन्य उत्तर काम नहीं कर सकते हैं । प्रत्येक कुंजी को उद्धरणों में लपेटने से यह सुनिश्चित होगा कि वे ठीक से नष्ट हो जाएंगे:

redis-cli --scan --pattern sf_* | awk '{print $1}' | sed "s/^/'/;s/$/'/" | xargs redis-cli del

2
यह स्क्रिप्ट सही काम करती है, 25000 से अधिक कुंजी के साथ परीक्षण किया गया है।
जोर्डी

1
आप भी इस हास्यास्पद अभिव्यक्ति `awk '{प्रिंट"' " '"' "$ 1" ' "'" ' "}'` का उपयोग कर awk में एकल उद्धरण जोड़ सकते हैं
रॉबर्टो Congiu

3

कुंजी के बजाय SCAN का उपयोग कर एक संस्करण (उत्पादन सर्वर के लिए अनुशंसित) और --pipexargs के बजाय।

मैं xargs पर पाइप पसंद करता हूं क्योंकि यह अधिक कुशल है और काम करता है जब आपकी कुंजियों में उद्धरण या अन्य विशेष वर्ण होते हैं जो आपके शेल को कोशिश और व्याख्या करते हैं। इस उदाहरण में रेगेक्स प्रतिस्थापन डबल कोट्स में कुंजी को लपेटता है, और अंदर किसी भी दोहरे उद्धरण से बच जाता है।

export REDIS_HOST=your.hostname.com
redis-cli -h "$REDIS_HOST" --scan --pattern "YourPattern*" > /tmp/keys
time cat /tmp/keys | perl -pe 's/"/\\"/g;s/^/DEL "/;s/$/"/;'  | redis-cli -h "$REDIS_HOST" --pipe

इस समाधान ने मेरे लिए भी लगभग 7 मी कुंजियों पर काम किया!
डैनी

2

यह प्रश्न का सीधा उत्तर नहीं है, लेकिन जब से मैं अपने स्वयं के उत्तरों की खोज कर रहा हूं, मैं इसे यहां साझा करूंगा।

यदि आपके पास दसियों या सैकड़ों लाखों कीज़ हैं जिन्हें आपको मिलान करना है, तो यहां दिए गए उत्तर महत्वपूर्ण समय (मिनटों?) के लिए रिडिस गैर-उत्तरदायी होंगे और मेमोरी खपत के कारण संभावित रूप से क्रैश हो सकते हैं (सुनिश्चित करें, बैकग्राउंड सेव करें आपके ऑपरेशन के बीच में किक)।

निम्नलिखित दृष्टिकोण निर्विवाद रूप से बदसूरत है, लेकिन मुझे एक बेहतर नहीं मिला। एटमॉसिटी यहां सवालों से बाहर है, इस मामले में मुख्य लक्ष्य रेडिस को बनाए रखना है और समय का 100% उत्तरदायी है। यह पूरी तरह से काम करेगा यदि आपके पास डेटाबेस में आपकी सभी चाबियाँ हैं और आपको किसी भी पैटर्न से मेल खाने की आवश्यकता नहीं है, लेकिन प्रकृति को अवरुद्ध करने के कारण http://redis.io/commands/FLUSHDB का उपयोग नहीं कर सकते ।

आइडिया सरल है: एक स्क्रिप्ट लिखें जो एक लूप में चलती है और http://redis.io/commands/SCAN या http://redis.io/commands/RANDOMKEY जैसे O (1) ऑपरेशन का उपयोग कर कुंजी, चेक प्राप्त करता है यदि वे पैटर्न से मिलान करें (यदि आपको इसकी आवश्यकता है) और http://redis.io/commands/DEL उन्हें एक-एक करके।

यदि ऐसा करने का कोई बेहतर तरीका है, तो कृपया मुझे बताएं, मैं उत्तर को अपडेट करूंगा।

उदाहरण के लिए रूबी में रैंडम के साथ कार्यान्वयन, एक रेक कार्य के रूप में, कुछ का एक गैर अवरुद्ध विकल्प redis-cli -n 3 flushdb:

desc 'Cleanup redis'
task cleanup_redis: :environment do
  redis = Redis.new(...) # connection to target database number which needs to be wiped out
  counter = 0
  while key = redis.randomkey               
    puts "Deleting #{counter}: #{key}"
    redis.del(key)
    counter += 1
  end
end

2

यह FastoRedis में "निकालें शाखा" कार्यक्षमता के माध्यम से सरल है , बस उस शाखा का चयन करें जिसे आप निकालना चाहते हैं।

यहाँ छवि विवरण दर्ज करें


क्या यह ऐसा परमाणु से होता है? और यह कोड में कैसे मदद करता है ?
मैथ्यू पढ़ें

2

कृपया इस आदेश का उपयोग करें और प्रयास करें:

redis-cli --raw keys "$PATTERN" | xargs redis-cli del

परमाणु नहीं, और अन्य उत्तरों की नकल करता है।
मैथ्यू पढ़ें

1

मैंने ऊपर बताए गए अधिकांश तरीकों की कोशिश की, लेकिन उन्होंने मेरे लिए काम नहीं किया, कुछ खोजों के बाद मुझे ये अंक मिले:

  • यदि आपके पास रेडिस पर एक से अधिक डीबी है तो आपको डेटाबेस का उपयोग करके निर्धारित करना चाहिए -n [number]
  • आप कुछ ही कुंजी का उपयोग अगर del, लेकिन अगर वहाँ हजारों या कुंजी के लाखों रहे हैं इसका इस्तेमाल बेहतर है unlinkक्योंकि अनलिंक गैर अवरुद्ध है , जबकि डेल अधिक जानकारी के लिए, ब्लॉक कर रहा है यह पेज अनलिंक बनाम डेल
  • भी keysडेल की तरह हैं और अवरुद्ध है

इसलिए मैंने पैटर्न द्वारा कुंजियों को हटाने के लिए इस कोड का उपयोग किया:

 redis-cli -n 2 --scan --pattern '[your pattern]' | xargs redis-cli -n 2 unlink 

0

गरीब आदमी का परमाणु जन-विलोप?

हो सकता है कि आप उन सभी को भविष्य में कुछ मिनटों की तरह एक ही सेकंड में निर्यात कर सकें - और फिर उस समय तक प्रतीक्षा करें और उन सभी को उसी समय "आत्म-विनाश" देखें।

लेकिन मैं वास्तव में निश्चित नहीं हूं कि परमाणु कैसे होंगे।


0

अब, आप एक रेडिस क्लाइंट का उपयोग कर सकते हैं और पहले SCAN (पैटर्न मिलान का समर्थन करता है) और फिर प्रत्येक कुंजी को अलग-अलग DEL कर सकते हैं।

हालाँकि, यहाँ एक संरक्षक-मिलान-डेल बनाने के लिए आधिकारिक रेडिस जीथब पर एक मुद्दा है , इसे उपयोगी मानने पर इसे थोड़ा प्यार दिखाएं!


-1

मैं कुछ उपकरण होने या लूआ अभिव्यक्ति को निष्पादित करने से संबंधित सभी उत्तरों का समर्थन करता हूं।

मेरी तरफ से एक और विकल्प:

हमारे उत्पादन और पूर्व-उत्पादन डेटाबेस में हजारों कीज़ हैं। समय-समय पर हमें कुछ चाबियों (कुछ मुखौटा द्वारा) को हटाने की जरूरत है, कुछ मानदंडों आदि द्वारा संशोधित किया जाता है, ज़ाहिर है, सीएलआई से इसे मैन्युअल रूप से करने का कोई तरीका नहीं है, विशेष रूप से शार्डिंग (प्रत्येक भौतिक में 512 तार्किक डीएस)।

इस काम के लिए मैं जावा क्लाइंट टूल लिखता हूं जो यह सब काम करता है। चाबियाँ हटाने के मामले में उपयोगिता बहुत सरल हो सकती है, केवल एक ही वर्ग वहां:

public class DataCleaner {

    public static void main(String args[]) {
        String keyPattern = args[0];
        String host = args[1];
        int port = Integer.valueOf(args[2]);
        int dbIndex = Integer.valueOf(args[3]);

        Jedis jedis = new Jedis(host, port);

        int deletedKeysNumber = 0;
        if(dbIndex >= 0){
            deletedKeysNumber += deleteDataFromDB(jedis, keyPattern, dbIndex);
        } else {
            int dbSize = Integer.valueOf(jedis.configGet("databases").get(1));
            for(int i = 0; i < dbSize; i++){
                deletedKeysNumber += deleteDataFromDB(jedis, keyPattern, i);
            }
        }

        if(deletedKeysNumber == 0) {
            System.out.println("There is no keys with key pattern: " + keyPattern + " was found in database with host: " + host);
        }
    }

    private static int deleteDataFromDB(Jedis jedis, String keyPattern, int dbIndex) {
        jedis.select(dbIndex);
        Set<String> keys = jedis.keys(keyPattern);
        for(String key : keys){
            jedis.del(key);
            System.out.println("The key: " + key + " has been deleted from database index: " + dbIndex);
        }

        return keys.size();
    }

}


-3

स्प्रिंग RedisTemplate ही कार्यक्षमता प्रदान करता है। नवीनतम संस्करण में RedissonClient ने "deleteByPattern" कार्यक्षमता को हटा दिया है।

Set<String> keys = redisTemplate.keys("geotag|*");
redisTemplate.delete(keys);

2
मैंने रेडिसन नमूना कोड अपडेट किया। आपका कोड परमाणु दृष्टिकोण में नहीं है जैसे Redisson करता है। नई कुंजियाँ keysऔर deleteविधियों के इनवॉइस के बीच प्रकट हो सकती हैं ।
निकिता कोक्षाश्रो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.