********************************************************************************* * * * SOFTWARE CONFIGURATION AND TWEAKING * * * ********************************************************************************* //--------- MySQL --------------------------------------------------------------- We're currently using the following MySQL configuration on an octo core Intel E5430 2.66GHz box with 16GB of RAM and 6 SAS hard drives in RAID 10. MySQL constantly uses uses between 2% and 65% of one core, and 63.8% of our RAM. This is our configuration file - adjust the numbers for your hardware accordingly. # Begin MySQL configuration [client] port = 3306 socket = /var/lib/mysql/mysql.sock [mysqld] skip-locking port = 3306 datadir = /var/lib/mysql socket = /var/lib/mysql/mysql.sock log-error = /var/log/mysqld.log pid-file = /var/run/mysqld/mysqld.pid ft_min_word_len = 2 ft_stopword_file = default_storage_engine = innodb max_connections = 2500 thread_cache = 800 table_cache = 2024 binlog_cache_size = 2M max_allowed_packet = 16M net_buffer_length = 16M join_buffer_size = 128M max_heap_table_size = 4G record_buffer = 32M sort_buffer_size = 32M tmp_table_size = 2G bulk_insert_buffer_size = 16M key_buffer = 256M preload_buffer_size = 32M read_buffer_size = 4M read_rnd_buffer_size = 8M myisam_sort_buffer_size = 64M innodb innodb_buffer_pool_size = 8G innodb_file_per_table innodb_log_buffer_size = 64M innodb_log_file_size = 1G innodb_support_xa = 0 innodb_flush_method = O_DIRECT innodb_data_file_path = ibdata1:10M:autoextend innodb_log_files_in_group = 2 innodb_thread_concurrency = 4 query_cache_size = 0 query_cache_type = 1 query_cache_limit = 4M log-slow-queries long_query_time = 10 delay-key-write = ALL skip-name-resolve sync_binlog = 0 [mysqldump] quick max_allowed_packet = 16M [mysql] no-auto-rehash [isamchk] key_buffer = 512M sort_buffer_size = 512M read_buffer = 4M write_buffer = 4M [myisamchk] ft_min_word_len = 2 key_buffer = 512M sort_buffer_size = 512M read_buffer = 32M write_buffer = 32M [mysqlhotcopy] interactive-timeout [mysqld_safe] log-error = /var/log/mysqld.log pid-file = /var/run/mysqld/mysqld.pid # End MySQL configuration Things you should take note of: - ft_min_word_len is 2. We use fulltext for searching torrent titles, which often have small words in them. - ft_stopword_file is blank. Stopwords are lame when you're searching in torrent titles. - The query cache is off. Gazelle handles its own caching - all the query cache will do is fill itself up. //--------- memcached ----------------------------------------------------------- ===== Start-up and configuration ===== Memcache requires almost no configuration whatsoever, which is pretty useful. All of its options are set with the command you use when you start it up. This is the command we use: /usr/local/bin/memcached -d -m 1024 -l 127.0.0.1 -p 11211 -u nobody This starts up memcached as a daemon, gives it a maximum memory usage of 1 gig (it's currently using 9038M), binds it to port 11211 on localhost, and runs as the user 'nobody'. Once it's running, no additional configuration is required. ===== Managing memcached ===== memcached doesn't have a command-line frontend - however, you can use leethax in order to manage it. Open up a shell or your server and type this: telnet 127.0.0.1 11211 You can now communicate with memcached by typing in the commands outlined in the memcache protocol. See: http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt The only commands we use on a regular basis are 'stats' (gives you an overview of the current stats), and 'flush_all' (clear the entire cache). ===== Running multiple instances ===== If you're running 2 sites on the same server, you'll find that the caches conflict with each other. Fortunately, there is an easy fix - simply run two instances of memcached on different ports. Eg: /usr/local/bin/memcached -d -m 1024 -l 127.0.0.1 -p 11211 -u nobody /usr/local/bin/memcached -d -m 1024 -l 127.0.0.1 -p 11212 -u nobody Then set one of your sites to connect to port 11211, and set the other to connect to port 11212. This can be done by editing class_cache.php. //--------- Apache -------------------------------------------------------------- We run 2 httpds - apache for dynamic content, and lighttpd for static content (which is why there's the STATIC_SERVER configuration option in config.php). We stripped our apache down to as few modules as possible, and disabled .htaccess files. We run prefork, with the following configuration: ## Settings ## Timeout 30 MaxKeepAliveRequests 20 KeepAliveTimeout 20 ServerTokens Prod ServerSignature Off KeepAlive Off UseCanonicalName Off HostnameLookups Off EnableMMAP Off EnableSendfile On ## Prefork ## StartServers 10 MinSpareServers 8 MaxSpareServers 20 ServerLimit 380 MaxClients 380 MaxRequestsPerChild 4000 We also have the following configuration in place to prevent people from poking around: Order deny,allow Deny from all Order deny,allow Deny from all Order deny,allow Deny from all Order deny,allow Deny from all # Standard Security Order deny,allow Deny from all //--------- Lighttpd ------------------------------------------------------------ As we don't run lighttpd as a dynamic content server, this document will only cover running it as a server for static content. You really don't need much at all to run lighttpd for this purpose: server.modules = ("mod_access") server.document-root = "/path/to/gazelle/static/" ... Bunch of default lighttpd stuff, then: # Stop people from looking at your source code static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" ) //--------- Other stuff --------------------------------------------------------- ===== Security ===== As a firewall, we run APF. We also run BFD to detect and ban brute-force attempts. For protection against DDoS attacks, we recommend DDoS deflate. ===== IRC ===== Right now, our IRC network runs under UnrealIRCd and anope - however, we plan to switch to InspIRCd and anope shortly. InspIRCd is much easier to set up and customize than Unreal. ===== Version control ===== For managing the code, there is no replacement for SVN. Check out a working copy into your server root, and run the site off it. You can make it automatically update the site with a post-commit hook like this: #!/bin/bash svn update --username update --password longpassword /var/www/your/site/