Add listen_interface and rpc_interface options patch by Matt Kennedy; reviewed by Tupshin Harper and jbellis for CASSANDRA-7417
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/5e4b8f53 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/5e4b8f53 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/5e4b8f53 Branch: refs/heads/trunk Commit: 5e4b8f535fb2b176335ba29a59302b08c3c23766 Parents: 37abae6 Author: Jonathan Ellis <jbel...@apache.org> Authored: Fri Jul 11 23:36:13 2014 -0500 Committer: Jonathan Ellis <jbel...@apache.org> Committed: Fri Jul 11 23:36:13 2014 -0500 ---------------------------------------------------------------------- CHANGES.txt | 1 + conf/cassandra.yaml | 22 ++++++--- .../org/apache/cassandra/config/Config.java | 2 + .../cassandra/config/DatabaseDescriptor.java | 49 ++++++++++++++++++-- 4 files changed, 62 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/5e4b8f53/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 27c28ae..080c0bc 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.1.1 + * Add listen_interface and rpc_interface options (CASSANDRA-7417) * Fail to start if commit log replay detects a problem (CASSANDRA-7125) * Improve schema merge performance (CASSANDRA-7444) * Fix NPE when unknown prepared statement ID is used (CASSANDRA-7454) http://git-wip-us.apache.org/repos/asf/cassandra/blob/5e4b8f53/conf/cassandra.yaml ---------------------------------------------------------------------- diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml index 4d97e86..061b89d 100644 --- a/conf/cassandra.yaml +++ b/conf/cassandra.yaml @@ -337,17 +337,20 @@ storage_port: 7000 # encryption_options ssl_storage_port: 7001 -# Address to bind to and tell other Cassandra nodes to connect to. You -# _must_ change this if you want multiple nodes to be able to -# communicate! -# +# Address or interface to bind to and tell other Cassandra nodes to connect to. +# You _must_ change this if you want multiple nodes to be able to communicate! +# +# Set listen_address OR listen_interface, not both. Interfaces must correspond +# to a single address, IP aliasing is not supported. +# # Leaving it blank leaves it up to InetAddress.getLocalHost(). This # will always do the Right Thing _if_ the node is properly configured # (hostname, name resolution, etc), and the Right Thing is to use the # address associated with the hostname (it might not be). # -# Setting this to 0.0.0.0 is always wrong. +# Setting listen_address to 0.0.0.0 is always wrong. listen_address: localhost +# listen_interface: eth0 # Address to broadcast to other Cassandra nodes # Leaving this blank will set it to the same value as listen_address @@ -376,15 +379,20 @@ native_transport_port: 9042 # Whether to start the thrift rpc server. start_rpc: true -# The address to bind the Thrift RPC service and native transport +# The address or interface to bind the Thrift RPC service and native transport # server to. # -# Leaving this blank has the same effect as on listen_address +# Set rpc_address OR rpc_interface, not both. Interfaces must correspond +# to a single address, IP aliasing is not supported. +# +# Leaving rpc_address blank has the same effect as on listen_address # (i.e. it will be based on the configured hostname of the node). # # Note that unlike listen_address, you can specify 0.0.0.0, but you must also # set broadcast_rpc_address to a value other than 0.0.0.0. rpc_address: localhost +# rpc_interface: eth1 + # port for Thrift to listen for clients on rpc_port: 9160 http://git-wip-us.apache.org/repos/asf/cassandra/blob/5e4b8f53/src/java/org/apache/cassandra/config/Config.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/config/Config.java b/src/java/org/apache/cassandra/config/Config.java index 4d4a95b..4b3c0e5 100644 --- a/src/java/org/apache/cassandra/config/Config.java +++ b/src/java/org/apache/cassandra/config/Config.java @@ -100,11 +100,13 @@ public class Config public Integer storage_port = 7000; public Integer ssl_storage_port = 7001; public String listen_address; + public String listen_interface; public String broadcast_address; public String internode_authenticator; public Boolean start_rpc = true; public String rpc_address; + public String rpc_interface; public String broadcast_rpc_address; public Integer rpc_port = 9160; public Integer rpc_listen_backlog = 50; http://git-wip-us.apache.org/repos/asf/cassandra/blob/5e4b8f53/src/java/org/apache/cassandra/config/DatabaseDescriptor.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java index 5a2f26f..bcbd748 100644 --- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java +++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java @@ -21,12 +21,15 @@ import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.Enumeration; import java.util.List; import java.util.Map; import java.util.Set; @@ -37,7 +40,6 @@ import com.google.common.collect.ImmutableSet; import com.google.common.primitives.Longs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.apache.cassandra.auth.AllowAllAuthenticator; import org.apache.cassandra.auth.AllowAllAuthorizer; import org.apache.cassandra.auth.AllowAllInternodeAuthenticator; @@ -298,8 +300,12 @@ public class DatabaseDescriptor if (conf.memtable_flush_writers < 1) throw new ConfigurationException("memtable_flush_writers must be at least 1"); - /* Local IP or hostname to bind services to */ - if (conf.listen_address != null) + /* Local IP, hostname or interface to bind services to */ + if (conf.listen_address != null && conf.listen_interface != null) + { + throw new ConfigurationException("Set listen_address OR listen_interface, not both"); + } + else if (conf.listen_address != null) { if (conf.listen_address.equals("0.0.0.0")) throw new ConfigurationException("listen_address cannot be 0.0.0.0!"); @@ -312,6 +318,21 @@ public class DatabaseDescriptor throw new ConfigurationException("Unknown listen_address '" + conf.listen_address + "'"); } } + else if (conf.listen_interface != null) + { + try + { + Enumeration<InetAddress> addrs = NetworkInterface.getByName(conf.listen_interface).getInetAddresses(); + listenAddress = addrs.nextElement(); + if (addrs.hasMoreElements()) + throw new ConfigurationException("Interface " + conf.listen_interface +" can't have more than one address"); + } + catch (SocketException e) + { + throw new ConfigurationException("Unknown network interface in listen_interface " + conf.listen_interface); + } + + } /* Gossip Address to broadcast */ if (conf.broadcast_address != null) @@ -331,8 +352,12 @@ public class DatabaseDescriptor } } - /* Local IP or hostname to bind RPC server to */ - if (conf.rpc_address != null) + /* Local IP, hostname or interface to bind RPC server to */ + if (conf.rpc_address != null && conf.rpc_interface != null) + { + throw new ConfigurationException("Set rpc_address OR rpc_interface, not both"); + } + else if (conf.rpc_address != null) { try { @@ -343,6 +368,20 @@ public class DatabaseDescriptor throw new ConfigurationException("Unknown host in rpc_address " + conf.rpc_address); } } + else if (conf.rpc_interface != null) + { + try + { + Enumeration<InetAddress> addrs = NetworkInterface.getByName(conf.rpc_interface).getInetAddresses(); + rpcAddress = addrs.nextElement(); + if (addrs.hasMoreElements()) + throw new ConfigurationException("Interface " + conf.rpc_interface +" can't have more than one address"); + } + catch (SocketException e) + { + throw new ConfigurationException("Unknown network interface in rpc_interface " + conf.rpc_interface); + } + } else { rpcAddress = FBUtilities.getLocalAddress();