From 8c2937adc39184f4cdb8db1c21ce6a372c130636 Mon Sep 17 00:00:00 2001 From: Michael Bradshaw Date: Fri, 10 May 2013 14:20:43 -0700 Subject: [PATCH] A number of updates to the cookbook for Redis: - Updated redis.conf.erb from Redis 2.x config - Added a number of options configurable via attributes, with defaults based on fresh install. - Added option to specify a package version for installing Redis. Installs latest if not provided. - Create db path directory specifically. --- redis/attributes/default.rb | 11 ++ redis/metadata.rb | 2 +- redis/recipes/server.rb | 9 ++ redis/templates/default/redis.conf.erb | 165 ++++++++++++++++++++----- 4 files changed, 158 insertions(+), 29 deletions(-) diff --git a/redis/attributes/default.rb b/redis/attributes/default.rb index f458c15..0c93a25 100644 --- a/redis/attributes/default.rb +++ b/redis/attributes/default.rb @@ -26,3 +26,14 @@ default[:redis][:vm][:page_size] = "32" default[:redis][:vm][:pages] = "134217728" default[:redis][:vm][:max_threads] = "4" +# set [:redis][:maxmemory] in override attributes if desired +default[:redis][:maxmemory] = nil +default[:redis][:maxmemory_policy] = "volatile-lru" +default[:redis][:hash_max_zipmap_entries] = "64" +default[:redis][:hash_max_zipmap_value] = "512" +default[:redis][:list_max_ziplist_entries] = "512" +default[:redis][:list_max_ziplist_value] = "64" +default[:redis][:set_max_intset_entries] = "512" +default[:redis][:loglevel] = "warning" +default[:redis][:db_path] = "/var/lib/redis" +default[:redis][:save_interval] = "900 1" diff --git a/redis/metadata.rb b/redis/metadata.rb index 9ac41fc..9917ab5 100644 --- a/redis/metadata.rb +++ b/redis/metadata.rb @@ -3,5 +3,5 @@ license "Apache 2.0" description "Installs/configures redis" long_description IO.read(File.join(File.dirname(__FILE__), 'README.rdoc')) -version "1.0.0" +version "2.0.0" supports "ubuntu" diff --git a/redis/recipes/server.rb b/redis/recipes/server.rb index dbf3c85..0647566 100644 --- a/redis/recipes/server.rb +++ b/redis/recipes/server.rb @@ -19,9 +19,18 @@ package "redis" do package_name "redis-server" + version node[:redis][:version] if node[:redis][:version] action :install end +directory node[:redis][:db_path] do + owner "redis" + group "redis" + mode 0755 + action :create + recursive true +end + service "redis" do service_name "redis-server" supports :status => true, :restart => true diff --git a/redis/templates/default/redis.conf.erb b/redis/templates/default/redis.conf.erb index 067c676..20d469e 100644 --- a/redis/templates/default/redis.conf.erb +++ b/redis/templates/default/redis.conf.erb @@ -1,5 +1,5 @@ -# Redis configuration file example - +# Config file populated by Chef +<% redis_2_4 = (node['redis']['version'].sub(/[0-9]*:/, '').split('.').map(&:to_i) <=> [2, 4]) < 0 %> # Note on units: when memory size is needed, it is possible to specifiy # it in the usual form of 1k 5GB 4M and so forth: # @@ -20,7 +20,8 @@ daemonize yes # default. You can specify a custom pid file location here. pidfile /var/run/redis.pid -# Accept connections on the specified port, default is 6379 +# Accept connections on the specified port, default is 6379. +# If port 0 is specified Redis will not listen on a TCP socket. port <%= @listen_port %> # If you want you can bind a single interface, if the bind option is not @@ -28,6 +29,12 @@ port <%= @listen_port %> # bind <%= @listen_addr %> +# Specify the path for the unix socket that will be used to listen for +# incoming connections. There is no default, so Redis will not listen +# on a unix socket when not specified. +# +# unixsocket /tmp/redis.sock + # Close the connection after a client is idle for N seconds (0 to disable) timeout 300 @@ -37,17 +44,27 @@ timeout 300 # verbose (many rarely useful info, but not a mess like the debug level) # notice (moderately verbose, what you want in production probably) # warning (only very important / critical messages are logged) -loglevel verbose +loglevel <%= @loglevel %> # Specify the log file name. Also 'stdout' can be used to force # Redis to log on the standard output. Note that if you use standard # output for logging but daemonize, logs will be sent to /dev/null logfile /var/log/redis/redis-server.log +# To enable logging to the system logger, just set 'syslog-enabled' to yes, +# and optionally update the other syslog parameters to suit your needs. +# syslog-enabled no + +# Specify the syslog identity. +# syslog-ident redis + +# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. +# syslog-facility local0 + # Set the number of databases. The default database is DB 0, you can select # a different one on a per-connection basis using SELECT where # dbid is a number between 0 and 'databases'-1 -databases 16 +databases 100 ################################ SNAPSHOTTING ################################# # @@ -65,9 +82,7 @@ databases 16 # # Note: you can disable saving at all commenting all the "save" lines. -save 900 1 -save 300 10 -save 60 10000 +save <%= @save_interval %> # Compress string objects using LZF when dump .rdb databases? # For default that's set to 'yes' as it's almost always a win. @@ -82,11 +97,11 @@ dbfilename dump.rdb # # The DB will be written inside this directory, with the filename specified # above using the 'dbfilename' configuration directive. -# +# # Also the Append Only File will be created inside this directory. -# +# # Note that you must specify a directory here, not a file name. -dir /var/lib/redis +dir <%= @db_path %> ################################# REPLICATION ################################# @@ -104,6 +119,19 @@ dir /var/lib/redis # # masterauth +# When a slave lost the connection with the master, or when the replication +# is still in progress, the slave can act in two different ways: +# +# 1) if slave-serve-stale-data is set to 'yes' (the default) the slave will +# still reply to client requests, possibly with out of data data, or the +# data set may just be empty if this is the first synchronization. +# +# 2) if slave-serve-stale data is set to 'no' the slave will reply with +# an error "SYNC with master in progress" to all the kind of commands +# but to INFO and SLAVEOF. +# +slave-serve-stale-data yes + ################################## SECURITY ################################### # Require clients to issue AUTH before processing any other @@ -112,13 +140,29 @@ dir /var/lib/redis # # This should stay commented out for backward compatibility and because most # people do not need auth (e.g. they run their own servers). -# +# # Warning: since Redis is pretty fast an outside user can try up to # 150k passwords per second against a good box. This means that you should # use a very strong password otherwise it will be very easy to break. # # requirepass foobared +# Command renaming. +# +# It is possilbe to change the name of dangerous commands in a shared +# environment. For instance the CONFIG command may be renamed into something +# of hard to guess so that it will be still available for internal-use +# tools but not available for general clients. +# +# Example: +# +# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 +# +# It is also possilbe to completely kill a command renaming it into +# an empty string: +# +# rename-command CONFIG "" + ################################### LIMITS #################################### # Set the max number of connected clients at the same time. By default there @@ -147,6 +191,41 @@ dir /var/lib/redis # errors for write operations, and this may even lead to DB inconsistency. # # maxmemory +<% if @maxmemory %> +maxmemory <%= @maxmemory %> +<% end %> + +# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory +# is reached? You can select among five behavior: +# +# volatile-lru -> remove the key with an expire set using an LRU algorithm +# allkeys-lru -> remove any key accordingly to the LRU algorithm +# volatile-random -> remove a random key with an expire set +# allkeys->random -> remove a random key, any key +# volatile-ttl -> remove the key with the nearest expire time (minor TTL) +# noeviction -> don't expire at all, just return an error on write operations +# +# Note: with all the kind of policies, Redis will return an error on write +# operations, when there are not suitable keys for eviction. +# +# At the date of writing this commands are: set setnx setex append +# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd +# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby +# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby +# getset mset msetnx exec sort +# +# The default is: +# +# maxmemory-policy volatile-lru +maxmemory-policy <%= @maxmemory_policy %> + +# LRU and minimal TTL algorithms are not precise algorithms but approximated +# algorithms (in order to save memory), so you can select as well the sample +# size to check. For instance for default Redis will check three keys and +# pick the one that was used less recently, you can change the sample size +# using the following configuration directive. +# +# maxmemory-samples 3 ############################## APPEND ONLY MODE ############################### @@ -169,10 +248,10 @@ dir /var/lib/redis appendonly <%= @appendonly %> # The name of the append only file (default: "appendonly.aof") -# appendfilename appendonly.aof +#appendfilename appendonly.aof # The fsync() call tells the Operating System to actually write data on disk -# instead to wait for more data in the output buffer. Some OS will really flush +# instead to wait for more data in the output buffer. Some OS will really flush # data on disk, some other OS will just try to do it ASAP. # # Redis supports three different modes: @@ -191,11 +270,31 @@ appendonly <%= @appendonly %> # # If unsure, use "everysec". -# appendfsync always +appendfsync <%= @appendfsync %> # appendfsync everysec # appendfsync no -appendfsync <%= @appendfsync %> +# When the AOF fsync policy is set to always or everysec, and a background +# saving process (a background save or AOF log background rewriting) is +# performing a lot of I/O against the disk, in some Linux configurations +# Redis may block too long on the fsync() call. Note that there is no fix for +# this currently, as even performing fsync in a different thread will block +# our synchronous write(2) call. +# +# In order to mitigate this problem it's possible to use the following option +# that will prevent fsync() from being called in the main process while a +# BGSAVE or BGREWRITEAOF is in progress. +# +# This means that while another child is saving the durability of Redis is +# the same as "appendfsync none", that in pratical terms means that it is +# possible to lost up to 30 seconds of log in the worst scenario (with the +# default Linux settings). +# +# If you have latency problems turn this to "yes". Otherwise leave it as +# "no" that is the safest pick from the point of view of durability. +no-appendfsync-on-rewrite no + +<% if redis_2_4 -%> ################################ VIRTUAL MEMORY ############################### # Virtual Memory allows Redis to work with datasets bigger than the actual @@ -207,22 +306,21 @@ appendfsync <%= @appendfsync %> # To enable VM just set 'vm-enabled' to yes, and set the following three # VM parameters accordingly to your needs. -# vm-enabled no -# vm-enabled yes vm-enabled <%= @vm[:enabled] %> +# vm-enabled yes # This is the path of the Redis swap file. As you can guess, swap files # can't be shared by different Redis instances, so make sure to use a swap # file for every redis process you are running. Redis will complain if the # swap file is already in use. # -# The best kind of storage for the Redis swap file (that's accessed at random) +# The best kind of storage for the Redis swap file (that's accessed at random) # is a Solid State Disk (SSD). # # *** WARNING *** if you are using a shared hosting the default of putting # the swap file under /tmp is not secure. Create a dir with access granted # only to Redis user and configure Redis to create the swap file there. -vm-swap-file /var/lib/redis/redis.swap +vm-swap-file /tmp/redis.swap # vm-max-memory configures the VM to use at max the specified amount of # RAM. Everything that deos not fit will be swapped on disk *if* possible, that @@ -268,20 +366,31 @@ vm-pages <%= @vm[:pages] %> # The special value of 0 turn off threaded I/O and enables the blocking # Virtual Memory implementation. vm-max-threads <%= @vm[:max_threads] %> +<% end -%> ############################### ADVANCED CONFIG ############################### -# Glue small output buffers together in order to send small replies in a -# single TCP packet. Uses a bit more CPU but most of the times it is a win -# in terms of number of queries per second. Use 'yes' if unsure. -glueoutputbuf yes - # Hashes are encoded in a special way (much more memory efficient) when they # have at max a given numer of elements, and the biggest element does not # exceed a given threshold. You can configure this limits with the following # configuration directives. -hash-max-zipmap-entries 64 -hash-max-zipmap-value 512 +<% if redis_2_4 -%> +hash-max-zipmap-entries <%= @hash_max_zipmap_entries %> +hash-max-zipmap-value <%= @hash_max_zipmap_value %> +<% end -%> + +# Similarly to hashes, small lists are also encoded in a special way in order +# to save a lot of space. The special representation is only used when +# you are under the following limits: +list-max-ziplist-entries <%= @list_max_ziplist_entries %> +list-max-ziplist-value <%= @list_max_ziplist_value %> + +# Sets have a special encoding in just one case: when a set is composed +# of just strings that happens to be integers in radix 10 in the range +# of 64 bit signed integers. +# The following configuration setting sets the limit in the size of the +# set in order to use this special memory saving encoding. +set-max-intset-entries 512 # Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in # order to help rehashing the main Redis hash table (the one mapping top-level @@ -290,7 +399,7 @@ hash-max-zipmap-value 512 # that is rhashing, the more rehashing "steps" are performed, so if the # server is idle the rehashing is never complete and some more memory is used # by the hash table. -# +# # The default is to use this millisecond 10 times every second in order to # active rehashing the main dictionaries, freeing memory when possible. #