beetle 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +5 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +82 -0
  4. data/Rakefile +114 -0
  5. data/TODO +7 -0
  6. data/beetle.gemspec +127 -0
  7. data/etc/redis-master.conf +189 -0
  8. data/etc/redis-slave.conf +189 -0
  9. data/examples/README.rdoc +14 -0
  10. data/examples/attempts.rb +66 -0
  11. data/examples/handler_class.rb +64 -0
  12. data/examples/handling_exceptions.rb +73 -0
  13. data/examples/multiple_exchanges.rb +48 -0
  14. data/examples/multiple_queues.rb +43 -0
  15. data/examples/redis_failover.rb +65 -0
  16. data/examples/redundant.rb +65 -0
  17. data/examples/rpc.rb +45 -0
  18. data/examples/simple.rb +39 -0
  19. data/lib/beetle.rb +57 -0
  20. data/lib/beetle/base.rb +78 -0
  21. data/lib/beetle/client.rb +252 -0
  22. data/lib/beetle/configuration.rb +31 -0
  23. data/lib/beetle/deduplication_store.rb +152 -0
  24. data/lib/beetle/handler.rb +95 -0
  25. data/lib/beetle/message.rb +336 -0
  26. data/lib/beetle/publisher.rb +187 -0
  27. data/lib/beetle/r_c.rb +40 -0
  28. data/lib/beetle/subscriber.rb +144 -0
  29. data/script/start_rabbit +29 -0
  30. data/snafu.rb +55 -0
  31. data/test/beetle.yml +81 -0
  32. data/test/beetle/base_test.rb +52 -0
  33. data/test/beetle/bla.rb +0 -0
  34. data/test/beetle/client_test.rb +305 -0
  35. data/test/beetle/configuration_test.rb +5 -0
  36. data/test/beetle/deduplication_store_test.rb +90 -0
  37. data/test/beetle/handler_test.rb +105 -0
  38. data/test/beetle/message_test.rb +744 -0
  39. data/test/beetle/publisher_test.rb +407 -0
  40. data/test/beetle/r_c_test.rb +9 -0
  41. data/test/beetle/subscriber_test.rb +263 -0
  42. data/test/beetle_test.rb +5 -0
  43. data/test/test_helper.rb +20 -0
  44. data/tmp/master/.gitignore +2 -0
  45. data/tmp/slave/.gitignore +3 -0
  46. metadata +192 -0
@@ -0,0 +1,5 @@
1
+ *.log
2
+ doc
3
+ pkg
4
+ site
5
+ test/coverage
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 XING AG
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,82 @@
1
+ = Beetle
2
+
3
+ High Availability AMQP Messaging with Redundant Queues
4
+
5
+ == About
6
+
7
+ Beetle grew out of a project to improve an existing ActiveMQ based messaging
8
+ infrastructure. It offers the following features:
9
+
10
+ * High Availability (by using multiple message broker instances)
11
+ * Redundancy (by replicating queues)
12
+ * Simple client API (by encapsulating the publishing/ deduplication logic)
13
+
14
+ More information can be found on the {project website}[http://xing.github.com/beetle].
15
+
16
+ == Usage
17
+
18
+ === Configuration
19
+ # configure machines
20
+
21
+ Beetle.config do |c|
22
+ config.servers = "broker1:5672, broker2:5672"
23
+ config.redis_hosts = "redis1:6379, redis2:6379"
24
+ end
25
+
26
+ # instantiate a beetle client
27
+
28
+ b = Beetle::Client.new
29
+
30
+ # configure exchanges, queues, bindings, messages and handlers
31
+
32
+ b.configure do |config|
33
+ config.queue :test
34
+ config.message :test
35
+ config.handler(:test) { |message| puts message.data }
36
+ end
37
+
38
+ === Publishing
39
+ b.publish :test, "I'm a test message"
40
+
41
+ === Subscribing
42
+ b.listen
43
+
44
+ :include: examples/README.rdoc
45
+
46
+ == Prerequisites
47
+
48
+ To set up a redundant messaging system you will need
49
+ * at least 2 AMQP servers (we use {RabbitMQ}[http://www.rabbitmq.com/])
50
+ * at least one Redis server (better are two in a master/slave setup)
51
+
52
+ == Gem Dependencies
53
+
54
+ At runtime, Beetle will use
55
+ * {uuid4r}[http://github.com/skaes/uuid4r]
56
+ (which needs ossp-uuid)
57
+ * {bunny}[http://github.com/celldee/bunny]
58
+ * {redis-rb}[http://github.com/ezmobius/redis-rb]
59
+ (which needs {redis}[http://github.com/antirez/redis])
60
+ * {amqp}[http://github.com/tmm1/amqp]
61
+ (which is based on {eventmachine}[http://github.com/eventmachine/eventmachine])
62
+ * activesupport
63
+
64
+ For development, you'll need
65
+ * mocha
66
+ * rcov
67
+
68
+ == Authors
69
+
70
+ {Stefan Kaes}[http://github.com/skaes],
71
+ {Pascal Friederich}[http://github.com/paukul] and
72
+ {Ali Jelveh}[http://github.com/dudemeister].
73
+
74
+ You cand find out more about our work on our {dev blog}[http://devblog.xing.com].
75
+
76
+ Copyright (c) 2010 {XING AG}[http://www.xing.com/]
77
+
78
+ Released under the MIT license. For full details see MIT-LICENSE included in this
79
+ distribution.
80
+
81
+
82
+
@@ -0,0 +1,114 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'lib/beetle'
4
+ require 'rcov/rcovtask'
5
+
6
+ namespace :test do
7
+ namespace :coverage do
8
+ desc "Delete aggregate coverage data."
9
+ task(:clean) { rm_f "coverage.data" }
10
+ end
11
+
12
+ desc 'Aggregate code coverage'
13
+ task :coverage => "test:coverage:clean"
14
+
15
+ Rcov::RcovTask.new(:coverage) do |t|
16
+ t.libs << "test"
17
+ t.test_files = FileList["test/**/*_test.rb"]
18
+ t.output_dir = "test/coverage"
19
+ t.verbose = true
20
+ t.rcov_opts << "--exclude '.*' --include-file 'lib/beetle/'"
21
+ end
22
+ task :coverage do
23
+ system 'open test/coverage/index.html'
24
+ end if RUBY_PLATFORM =~ /darwin/
25
+ end
26
+
27
+
28
+ namespace :beetle do
29
+ task :test do
30
+ Beetle::Client.new.test
31
+ end
32
+
33
+ task :trace do
34
+ trap('INT'){ EM.stop_event_loop }
35
+ Beetle::Client.new.trace
36
+ end
37
+ end
38
+
39
+ namespace :rabbit do
40
+ def start(node_name, port)
41
+ script = File.expand_path(File.dirname(__FILE__)+"/script/start_rabbit")
42
+ puts "starting rabbit #{node_name} on port #{port}"
43
+ puts "type ^C a RETURN to abort"
44
+ sleep 1
45
+ exec "sudo #{script} #{node_name} #{port}"
46
+ end
47
+ desc "start rabbit instance 1"
48
+ task :start1 do
49
+ start "rabbit1", 5672
50
+ end
51
+ desc "start rabbit instance 2"
52
+ task :start2 do
53
+ start "rabbit2", 5673
54
+ end
55
+ end
56
+
57
+ namespace :redis do
58
+ def config_file(suffix)
59
+ File.expand_path(File.dirname(__FILE__)+"/etc/redis-#{suffix}.conf")
60
+ end
61
+ desc "start main redis"
62
+ task :start1 do
63
+ exec "redis-server #{config_file(:master)}"
64
+ end
65
+ desc "start slave redis"
66
+ task :start2 do
67
+ exec "redis-server #{config_file(:slave)}"
68
+ end
69
+ end
70
+
71
+ task :default do
72
+ Rake::Task[:test].invoke
73
+ end
74
+
75
+ Rake::TestTask.new do |t|
76
+ t.libs << "test"
77
+ t.test_files = FileList['test/**/*_test.rb']
78
+ t.verbose = true
79
+ end
80
+
81
+ require 'rake/rdoctask'
82
+
83
+ Rake::RDocTask.new do |rdoc|
84
+ rdoc.rdoc_dir = 'site/rdoc'
85
+ rdoc.title = 'Beetle'
86
+ rdoc.options << '--line-numbers' << '--inline-source' << '--quiet'
87
+ rdoc.rdoc_files.include('README.rdoc')
88
+ rdoc.rdoc_files.include('lib/**/*.rb')
89
+ end
90
+
91
+ begin
92
+ require 'jeweler'
93
+ Jeweler::Tasks.new do |gemspec|
94
+ gemspec.name = 'beetle'
95
+ gemspec.version = '0.1'
96
+ gemspec.summary = "High Availability AMQP Messaging with Redundant Queues"
97
+ gemspec.description = "A highly available, reliable messaging infrastructure"
98
+ gemspec.email = "developers@xing.com"
99
+ gemspec.homepage = "http://xing.github.com/beetle/"
100
+ gemspec.authors = ["Stefan Kaes", "Pascal Friederich", "Ali Jelveh"]
101
+ gemspec.add_dependency('uuid4r', '>=0.1.1')
102
+ gemspec.add_dependency('bunny', '>=0.6.0')
103
+ gemspec.add_dependency('redis', '>=0.1.2')
104
+ gemspec.add_dependency('amqp', '>=0.6.7')
105
+ gemspec.add_dependency('activesupport', '>=2.3.4')
106
+
107
+ gemspec.add_development_dependency('mocha')
108
+ gemspec.add_development_dependency('rcov')
109
+ end
110
+ Jeweler::GemcutterTasks.new
111
+ rescue LoadError
112
+ # puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
113
+ end
114
+
data/TODO ADDED
@@ -0,0 +1,7 @@
1
+ - docs
2
+ - example scripts
3
+ - let handlers decide dynamically how long to wait for a retry
4
+ - review log levels in all logger statements
5
+ - optimize redis accesses:
6
+ - combine multiple redis accesses into one
7
+ - ack redundant messages with attempts limit 1 immediately?
@@ -0,0 +1,127 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{beetle}
8
+ s.version = "0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Stefan Kaes", "Pascal Friederich", "Ali Jelveh"]
12
+ s.date = %q{2010-04-14}
13
+ s.description = %q{A highly available, reliable messaging infrastructure}
14
+ s.email = %q{developers@xing.com}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc",
17
+ "TODO"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "MIT-LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "TODO",
25
+ "beetle.gemspec",
26
+ "doc/redundant_queues.graffle",
27
+ "etc/redis-master.conf",
28
+ "etc/redis-slave.conf",
29
+ "examples/README.rdoc",
30
+ "examples/attempts.rb",
31
+ "examples/handler_class.rb",
32
+ "examples/handling_exceptions.rb",
33
+ "examples/multiple_exchanges.rb",
34
+ "examples/multiple_queues.rb",
35
+ "examples/redis_failover.rb",
36
+ "examples/redundant.rb",
37
+ "examples/rpc.rb",
38
+ "examples/simple.rb",
39
+ "lib/beetle.rb",
40
+ "lib/beetle/base.rb",
41
+ "lib/beetle/client.rb",
42
+ "lib/beetle/configuration.rb",
43
+ "lib/beetle/deduplication_store.rb",
44
+ "lib/beetle/handler.rb",
45
+ "lib/beetle/message.rb",
46
+ "lib/beetle/publisher.rb",
47
+ "lib/beetle/r_c.rb",
48
+ "lib/beetle/subscriber.rb",
49
+ "script/start_rabbit",
50
+ "snafu.rb",
51
+ "test/beetle.yml",
52
+ "test/beetle/base_test.rb",
53
+ "test/beetle/bla.rb",
54
+ "test/beetle/client_test.rb",
55
+ "test/beetle/configuration_test.rb",
56
+ "test/beetle/deduplication_store_test.rb",
57
+ "test/beetle/handler_test.rb",
58
+ "test/beetle/message_test.rb",
59
+ "test/beetle/publisher_test.rb",
60
+ "test/beetle/r_c_test.rb",
61
+ "test/beetle/subscriber_test.rb",
62
+ "test/beetle_test.rb",
63
+ "test/test_helper.rb",
64
+ "tmp/master/.gitignore",
65
+ "tmp/slave/.gitignore"
66
+ ]
67
+ s.homepage = %q{http://xing.github.com/beetle/}
68
+ s.rdoc_options = ["--charset=UTF-8"]
69
+ s.require_paths = ["lib"]
70
+ s.rubygems_version = %q{1.3.5}
71
+ s.summary = %q{High Availability AMQP Messaging with Redundant Queues}
72
+ s.test_files = [
73
+ "test/beetle/base_test.rb",
74
+ "test/beetle/bla.rb",
75
+ "test/beetle/client_test.rb",
76
+ "test/beetle/configuration_test.rb",
77
+ "test/beetle/deduplication_store_test.rb",
78
+ "test/beetle/handler_test.rb",
79
+ "test/beetle/message_test.rb",
80
+ "test/beetle/publisher_test.rb",
81
+ "test/beetle/r_c_test.rb",
82
+ "test/beetle/subscriber_test.rb",
83
+ "test/beetle_test.rb",
84
+ "test/test_helper.rb",
85
+ "examples/attempts.rb",
86
+ "examples/handler_class.rb",
87
+ "examples/handling_exceptions.rb",
88
+ "examples/multiple_exchanges.rb",
89
+ "examples/multiple_queues.rb",
90
+ "examples/redis_failover.rb",
91
+ "examples/redundant.rb",
92
+ "examples/rpc.rb",
93
+ "examples/simple.rb"
94
+ ]
95
+
96
+ if s.respond_to? :specification_version then
97
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
98
+ s.specification_version = 3
99
+
100
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
101
+ s.add_runtime_dependency(%q<uuid4r>, [">= 0.1.1"])
102
+ s.add_runtime_dependency(%q<bunny>, [">= 0.6.0"])
103
+ s.add_runtime_dependency(%q<redis>, [">= 0.1.2"])
104
+ s.add_runtime_dependency(%q<amqp>, [">= 0.6.7"])
105
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.3.4"])
106
+ s.add_development_dependency(%q<mocha>, [">= 0"])
107
+ s.add_development_dependency(%q<rcov>, [">= 0"])
108
+ else
109
+ s.add_dependency(%q<uuid4r>, [">= 0.1.1"])
110
+ s.add_dependency(%q<bunny>, [">= 0.6.0"])
111
+ s.add_dependency(%q<redis>, [">= 0.1.2"])
112
+ s.add_dependency(%q<amqp>, [">= 0.6.7"])
113
+ s.add_dependency(%q<activesupport>, [">= 2.3.4"])
114
+ s.add_dependency(%q<mocha>, [">= 0"])
115
+ s.add_dependency(%q<rcov>, [">= 0"])
116
+ end
117
+ else
118
+ s.add_dependency(%q<uuid4r>, [">= 0.1.1"])
119
+ s.add_dependency(%q<bunny>, [">= 0.6.0"])
120
+ s.add_dependency(%q<redis>, [">= 0.1.2"])
121
+ s.add_dependency(%q<amqp>, [">= 0.6.7"])
122
+ s.add_dependency(%q<activesupport>, [">= 2.3.4"])
123
+ s.add_dependency(%q<mocha>, [">= 0"])
124
+ s.add_dependency(%q<rcov>, [">= 0"])
125
+ end
126
+ end
127
+
@@ -0,0 +1,189 @@
1
+ # Redis configuration file example
2
+
3
+ # By default Redis does not run as a daemon. Use 'yes' if you need it.
4
+ # Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
5
+ daemonize no
6
+
7
+ # When run as a daemon, Redis write a pid file in /var/run/redis.pid by default.
8
+ # You can specify a custom pid file location here.
9
+ pidfile ./tmp/redis-master.pid
10
+
11
+ # Accept connections on the specified port, default is 6379
12
+ port 6379
13
+
14
+ # If you want you can bind a single interface, if the bind option is not
15
+ # specified all the interfaces will listen for connections.
16
+ #
17
+ # bind 127.0.0.1
18
+
19
+ # Close the connection after a client is idle for N seconds (0 to disable)
20
+ timeout 300
21
+
22
+ # Set server verbosity to 'debug'
23
+ # it can be one of:
24
+ # debug (a lot of information, useful for development/testing)
25
+ # notice (moderately verbose, what you want in production probably)
26
+ # warning (only very important / critical messages are logged)
27
+ loglevel debug
28
+
29
+ # Specify the log file name. Also 'stdout' can be used to force
30
+ # the demon to log on the standard output. Note that if you use standard
31
+ # output for logging but daemonize, logs will be sent to /dev/null
32
+ logfile stdout
33
+
34
+ # Set the number of databases. The default database is DB 0, you can select
35
+ # a different one on a per-connection basis using SELECT <dbid> where
36
+ # dbid is a number between 0 and 'databases'-1
37
+ databases 16
38
+
39
+ ################################ SNAPSHOTTING #################################
40
+ #
41
+ # Save the DB on disk:
42
+ #
43
+ # save <seconds> <changes>
44
+ #
45
+ # Will save the DB if both the given number of seconds and the given
46
+ # number of write operations against the DB occurred.
47
+ #
48
+ # In the example below the behaviour will be to save:
49
+ # after 900 sec (15 min) if at least 1 key changed
50
+ # after 300 sec (5 min) if at least 10 keys changed
51
+ # after 60 sec if at least 10000 keys changed
52
+ save 900 1
53
+ save 300 10
54
+ save 60 10000
55
+
56
+ # Compress string objects using LZF when dump .rdb databases?
57
+ # For default that's set to 'yes' as it's almost always a win.
58
+ # If you want to save some CPU in the saving child set it to 'no' but
59
+ # the dataset will likely be bigger if you have compressible values or keys.
60
+ rdbcompression yes
61
+
62
+ # The filename where to dump the DB
63
+ dbfilename dump.rdb
64
+
65
+ # For default save/load DB in/from the working directory
66
+ # Note that you must specify a directory not a file name.
67
+ dir ./tmp/master/
68
+
69
+ ################################# REPLICATION #################################
70
+
71
+ # Master-Slave replication. Use slaveof to make a Redis instance a copy of
72
+ # another Redis server. Note that the configuration is local to the slave
73
+ # so for example it is possible to configure the slave to save the DB with a
74
+ # different interval, or to listen to another port, and so on.
75
+ #
76
+ # slaveof <masterip> <masterport>
77
+
78
+ # If the master is password protected (using the "requirepass" configuration
79
+ # directive below) it is possible to tell the slave to authenticate before
80
+ # starting the replication synchronization process, otherwise the master will
81
+ # refuse the slave request.
82
+ #
83
+ # masterauth <master-password>
84
+
85
+ ################################## SECURITY ###################################
86
+
87
+ # Require clients to issue AUTH <PASSWORD> before processing any other
88
+ # commands. This might be useful in environments in which you do not trust
89
+ # others with access to the host running redis-server.
90
+ #
91
+ # This should stay commented out for backward compatibility and because most
92
+ # people do not need auth (e.g. they run their own servers).
93
+ #
94
+ # requirepass foobared
95
+
96
+ ################################### LIMITS ####################################
97
+
98
+ # Set the max number of connected clients at the same time. By default there
99
+ # is no limit, and it's up to the number of file descriptors the Redis process
100
+ # is able to open. The special value '0' means no limts.
101
+ # Once the limit is reached Redis will close all the new connections sending
102
+ # an error 'max number of clients reached'.
103
+ #
104
+ # maxclients 128
105
+
106
+ # Don't use more memory than the specified amount of bytes.
107
+ # When the memory limit is reached Redis will try to remove keys with an
108
+ # EXPIRE set. It will try to start freeing keys that are going to expire
109
+ # in little time and preserve keys with a longer time to live.
110
+ # Redis will also try to remove objects from free lists if possible.
111
+ #
112
+ # If all this fails, Redis will start to reply with errors to commands
113
+ # that will use more memory, like SET, LPUSH, and so on, and will continue
114
+ # to reply to most read-only commands like GET.
115
+ #
116
+ # WARNING: maxmemory can be a good idea mainly if you want to use Redis as a
117
+ # 'state' server or cache, not as a real DB. When Redis is used as a real
118
+ # database the memory usage will grow over the weeks, it will be obvious if
119
+ # it is going to use too much memory in the long run, and you'll have the time
120
+ # to upgrade. With maxmemory after the limit is reached you'll start to get
121
+ # errors for write operations, and this may even lead to DB inconsistency.
122
+ #
123
+ # maxmemory <bytes>
124
+
125
+ ############################## APPEND ONLY MODE ###############################
126
+
127
+ # By default Redis asynchronously dumps the dataset on disk. If you can live
128
+ # with the idea that the latest records will be lost if something like a crash
129
+ # happens this is the preferred way to run Redis. If instead you care a lot
130
+ # about your data and don't want to that a single record can get lost you should
131
+ # enable the append only mode: when this mode is enabled Redis will append
132
+ # every write operation received in the file appendonly.log. This file will
133
+ # be read on startup in order to rebuild the full dataset in memory.
134
+ #
135
+ # Note that you can have both the async dumps and the append only file if you
136
+ # like (you have to comment the "save" statements above to disable the dumps).
137
+ # Still if append only mode is enabled Redis will load the data from the
138
+ # log file at startup ignoring the dump.rdb file.
139
+ #
140
+ # The name of the append only file is "appendonly.log"
141
+ #
142
+ # IMPORTANT: Check the BGREWRITEAOF to check how to rewrite the append
143
+ # log file in background when it gets too big.
144
+
145
+ appendonly yes
146
+
147
+ # The fsync() call tells the Operating System to actually write data on disk
148
+ # instead to wait for more data in the output buffer. Some OS will really flush
149
+ # data on disk, some other OS will just try to do it ASAP.
150
+ #
151
+ # Redis supports three different modes:
152
+ #
153
+ # no: don't fsync, just let the OS flush the data when it wants. Faster.
154
+ # always: fsync after every write to the append only log . Slow, Safest.
155
+ # everysec: fsync only if one second passed since the last fsync. Compromise.
156
+ #
157
+ # The default is "always" that's the safer of the options. It's up to you to
158
+ # understand if you can relax this to "everysec" that will fsync every second
159
+ # or to "no" that will let the operating system flush the output buffer when
160
+ # it want, for better performances (but if you can live with the idea of
161
+ # some data loss consider the default persistence mode that's snapshotting).
162
+
163
+ # appendfsync always
164
+ appendfsync everysec
165
+ # appendfsync no
166
+
167
+ ############################### ADVANCED CONFIG ###############################
168
+
169
+ # Glue small output buffers together in order to send small replies in a
170
+ # single TCP packet. Uses a bit more CPU but most of the times it is a win
171
+ # in terms of number of queries per second. Use 'yes' if unsure.
172
+ glueoutputbuf yes
173
+
174
+ # Use object sharing. Can save a lot of memory if you have many common
175
+ # string in your dataset, but performs lookups against the shared objects
176
+ # pool so it uses more CPU and can be a bit slower. Usually it's a good
177
+ # idea.
178
+ #
179
+ # When object sharing is enabled (shareobjects yes) you can use
180
+ # shareobjectspoolsize to control the size of the pool used in order to try
181
+ # object sharing. A bigger pool size will lead to better sharing capabilities.
182
+ # In general you want this value to be at least the double of the number of
183
+ # very common strings you have in your dataset.
184
+ #
185
+ # WARNING: object sharing is experimental, don't enable this feature
186
+ # in production before of Redis 1.0-stable. Still please try this feature in
187
+ # your development environment so that we can test it better.
188
+ shareobjects no
189
+ shareobjectspoolsize 1024