Deleting ultra-large list

35 views
Skip to first unread message

Archie R

unread,
Apr 13, 2015, 2:28:57 PM4/13/15
to redi...@googlegroups.com

I've got a redis instance with 8GB of mem and a 7.5GB list that needs deleting.     We're running sentinel,  with masters and slaves etc.

Log onto master

redis-cli> DEL BIGOLELIST

....20 seconds pass....

Yay!   Lots of memory now.    But,  the delete took so long,  sentinel demoted this master to a slave.      A bit later,  BIGOLELIST replicates over from the new master.   Uh-oh.

We'll be able to clean this up by disabling Sentinel,  but seems like a bit of an issue.






Jan-Erik Rediger

unread,
Apr 13, 2015, 2:46:52 PM4/13/15
to redi...@googlegroups.com
This is a known issue, see https://github.com/antirez/redis/issues/2455
It can be tackled by `LAZYDEL` which is yet to be implemented (I got a
half-working PoC lying around, I just polish that and submit it), see
https://github.com/antirez/redis/issues/1748

You're best bet for now: Don't `DEL` it at once, but trim the list in
smaller part (or pop items off, possibly using a Lua script to avoid
sending all that data across the wire)
> --
> You received this message because you are subscribed to the Google Groups "Redis DB" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to redis-db+u...@googlegroups.com.
> To post to this group, send email to redi...@googlegroups.com.
> Visit this group at http://groups.google.com/group/redis-db.
> For more options, visit https://groups.google.com/d/optout.

Josiah Carlson

unread,
Apr 13, 2015, 5:35:14 PM4/13/15
to redi...@googlegroups.com, Jan-Erik Rediger
To follow up with this; if you need to have the key *not available* when your "deletion" starts, rename the key. After renaming the key, then do as Jan-Eric suggests and delete chunks at a time. As an example, here is a Python function that will do the rename and will slowly delete the list over time.

import uuid
import time

def delete_long_list(conn, key, ex_sleep=.001):
    # get a new unique key name
    nk = str(uuid.uuid4())
    # rename the key
    conn.rename(key, nk)
    # remove the first 1k elements until empty
    for _ in xrange(0, conn.llen(nk), 1000):
        conn.ltrim(nk, 1000, -1)
        if ex_sleep > 0:
            # give Redis some extra time between passes
            time.sleep(ex_sleep)

 - Josiah

Thomas Love

unread,
Apr 14, 2015, 3:26:47 AM4/14/15
to redi...@googlegroups.com
I'd argue the issue lies with your design. You are executing an O(N) command that takes X seconds, but you are considering your server failed after some time < X. 

As suggested, you could trim the list, or rename-trim, OR, reconfigure Sentinel to tolerate your 20-second blocks.

LAZYDEL will not come for free and would not imo be the best solution in general anyway.



Reply all
Reply to author
Forward
0 new messages