Last active
          December 14, 2023 14:14 
        
      - 
      
- 
        Save itamarhaber/d30b3c40a72a07f23c70 to your computer and use it in GitHub Desktop. 
    The fastest, type-agnostic way to copy a Redis key, as discussed in https://redislabs.com/blog/the-7th-principle-of-redis-we-optimize-for-joy
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | -- @desc: The fastest, type-agnostic way to copy a Redis key | |
| -- @usage: redis-cli --eval copy_key.lua <source> <dest> , [NX] | |
| local s = KEYS[1] | |
| local d = KEYS[2] | |
| if redis.call("EXISTS", d) == 1 then | |
| if type(ARGV[1]) == "string" and ARGV[1]:upper() == "NX" then | |
| return nil | |
| else | |
| redis.call("DEL", d) | |
| end | |
| end | |
| redis.call("RESTORE", d, 0, redis.call("DUMP", s)) | |
| return "OK" | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | foo@bar:~$ redis-benchmark -r 10000000 -n 10000000 -P 1000 lpush L __rand_int__ | |
| ====== lpush L __rand_int__ ====== | |
| 10000000 requests completed in 1.30 seconds | |
| … | |
| 814929.50 requests per second | |
| foo@bar:~$ redis-cli llen L | |
| (integer) 10030000 | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | -- @desc: copies a list with POP and PUSH | |
| -- @usage: redis-cli --eval copy_list_with_popnpush.lua <source> <dest> | |
| local s = KEYS[1] | |
| local d = KEYS[2] | |
| local l = redis.call("LLEN", s) | |
| local i = tonumber(l) | |
| while i > 0 do | |
| local v = redis.call("RPOPLPUSH", s, s) | |
| redis.call("LPUSH", d, v) | |
| i = i - 1 | |
| end | |
| return l | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | foo@bar:~$ time redis-cli --eval copy_list_with_popnpush.lua L T | |
| (integer) 10030000 | |
| real 0m23.579s | |
| user 0m0.000s | |
| sys 0m0.006s | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | -- @desc: copies a list with LRANGE | |
| -- @usage: redis-cli --eval copy_list_with_lrange.lua <source> <dest> | |
| local s = KEYS[1] | |
| local d = KEYS[2] | |
| local i = tonumber(redis.call("LLEN", s)) | |
| local j = 0 | |
| while j < i do | |
| local l = redis.call("LRANGE", s, j, j+99) | |
| redis.call("LPUSH", d, unpack(l)) | |
| j = j + 100 | |
| end | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | foo@bar:~$ redis-cli del T | |
| (integer) 1 | |
| foo@bar:~$ time redis-cli --eval copy_list_with_lrange.lua L T | |
| (integer) 10030000 | |
| real 0m11.148s | |
| user 0m0.000s | |
| sys 0m0.004s | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | foo@bar:~$ redis-cli del T | |
| (integer) 1 | |
| foo@bar:~$ time redis-cli sort L by nosort store T | |
| (integer) 10030000 | |
| real 0m2.390s | |
| user 0m0.000s | |
| sys 0m0.003s | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | foo@bar:~$ redis-cli del T | |
| (integer) 1 | |
| foo@bar:~$ time redis-cli --eval copy_key.lua L T | |
| "OK" | |
| real 0m1.661s | |
| user 0m0.000s | |
| sys 0m0.007s | 
For Sorted Sets, a self-union is actually faster. Source: http://stackoverflow.com/questions/32911604/intersection-of-two-or-more-sorted-sets/32980086#32980086
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment
  
            
RESTORE's newREPLACEmodifier could be used instead of theNX-triggeredDEL, but the latter is employed in this script to ensure compatibility with older versions.