BUSY
Fix Redis Error BUSY: Script Execution
Description
Error Message
BUSY Redis is busy running a script
Known Causes
3 known causesSolutions
3 solutions available1. Wait for Script to Complete easy
The simplest solution is to wait for the currently executing Lua script to finish. Redis is designed to block other commands during script execution to maintain atomicity and consistency. If the script is short-lived, this is often the most appropriate action.
Example Python retry logic:
```python
import redis
import time
r = redis.Redis(host='localhost', port=6379, db=0)
max_retries = 5
initial_delay = 0.1 # seconds
for attempt in range(max_retries):
try:
# Your Redis command here
r.set('mykey', 'myvalue')
print("Command executed successfully!")
break
except redis.exceptions.ResponseError as e:
if 'BUSY' in str(e):
delay = initial_delay * (2 ** attempt)
print(f"Redis busy, retrying in {delay:.2f} seconds...")
time.sleep(delay)
else:
print(f"An unexpected Redis error occurred: {e}")
break
except Exception as e:
print(f"An unexpected error occurred: {e}")
break
```
2. Optimize Long-Running Scripts medium
If the BUSY error is frequent or the script takes an unusually long time to execute, it suggests the Lua script itself might be inefficient. Optimizing the script's logic, reducing its complexity, or breaking it down into smaller, more manageable parts can significantly reduce execution time and prevent blocking.
- Excessive loops or iteration over large datasets.
- Redundant operations or computations.
- Inefficient data structures or access patterns.
- External calls or blocking operations within the script (though Redis Lua scripts are generally designed to be non-blocking internally, complex logic can still be slow).
Consider if the entire operation needs to be atomic within a single script, or if parts can be executed sequentially with appropriate error handling.
Instead of:
```lua
local keys = redis.call('KEYS', 'my_prefix:*')
local total = 0
for i, key in ipairs(keys) do
total = total + redis.call('GET', key)
end
return total
```
Consider a pattern that avoids `KEYS` and iterates with `SCAN` or uses a more efficient data structure if applicable, or a combination of commands that can be pipelined.
3. Adjust Redis Configuration for Script Execution advanced
In scenarios where long-running scripts are unavoidable and optimization is not feasible, you might consider adjusting Redis's `timeout` configuration. However, this is a last resort and can have significant implications for data consistency and server stability if not managed carefully. It's generally not recommended to increase the default script timeout significantly without a deep understanding of the risks.
Edit your `redis.conf` file and change the `lua-time-limit` directive:
```conf
# Default is 5000 (5 seconds)
lua-time-limit 10000 # Set to 10 seconds (example)
```
Example for systemd:
```bash
sudo systemctl restart redis
```
Example for init.d:
```bash
sudo service redis-server restart
```