(三)storm-kafka源碼走讀之如何構建一個KafkaSpout

來源:互聯網
上載者:User

標籤:storm   kafka   大資料   即時處理   

上一節介紹了config的相關資訊,這一節說下,這些參數分別是什麼,在zookeeper中的存放路徑是怎樣的,之前QQ群裡有很多不知道該怎麼傳入正確的參數來new 一個kafkaSpout,其主要還是參數傳遞正確就可。


看SpoutConfig的建構函式

public SpoutConfig(BrokerHosts hosts, String topic, String zkRoot, String id) {        super(hosts, topic);        this.zkRoot = zkRoot;        this.id = id;    }

需要一個BrokerHosts,看代碼:

public class ZkHosts implements BrokerHosts {    private static final String DEFAULT_ZK_PATH = "/brokers";    public String brokerZkStr = null;    public String brokerZkPath = null; // e.g., /kafka/brokers    public int refreshFreqSecs = 60;    public ZkHosts(String brokerZkStr, String brokerZkPath) {        this.brokerZkStr = brokerZkStr;        this.brokerZkPath = brokerZkPath;    }    public ZkHosts(String brokerZkStr) {        this(brokerZkStr, DEFAULT_ZK_PATH);    }}
需要brokerZKStr,這個其實就是hosts列表,多個host以逗號隔開,因為zookeeper解析string時是以逗號分隔的,這裡附上zookeeper的解析代碼

public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,            boolean canBeReadOnly)        throws IOException    {        LOG.info("Initiating client connection, connectString=" + connectString                + " sessionTimeout=" + sessionTimeout + " watcher=" + watcher);        watchManager.defaultWatcher = watcher;        ConnectStringParser connectStringParser = new ConnectStringParser(                connectString);        HostProvider hostProvider = new StaticHostProvider(                connectStringParser.getServerAddresses());        cnxn = new ClientCnxn(connectStringParser.getChrootPath(),                hostProvider, sessionTimeout, this, watchManager,                getClientCnxnSocket(), canBeReadOnly);        cnxn.start();    }

其中主要StringParser做解析的,看俺如何解析的就知道了

public ConnectStringParser(String connectString) {        // parse out chroot, if any        int off = connectString.indexOf('/');        if (off >= 0) {            String chrootPath = connectString.substring(off);            // ignore "/" chroot spec, same as null            if (chrootPath.length() == 1) {                this.chrootPath = null;            } else {                PathUtils.validatePath(chrootPath);                this.chrootPath = chrootPath;            }            connectString = connectString.substring(0, off);        } else {            this.chrootPath = null;        }        String hostsList[] = connectString.split(",");        for (String host : hostsList) {            int port = DEFAULT_PORT;            int pidx = host.lastIndexOf(':');            if (pidx >= 0) {                // otherwise : is at the end of the string, ignore                if (pidx < host.length() - 1) {                    port = Integer.parseInt(host.substring(pidx + 1));                }                host = host.substring(0, pidx);            }            serverAddresses.add(InetSocketAddress.createUnresolved(host, port));        }    }

好了,這裡就說到這了。

剛才說到brokerZKStr需要,還有一個參數就是zkpath,這個可以自己定,也有個預設值 “/brokers”

SpoutConfig還有個zkroot,這個zkroot其實就是Consumer端消費的資訊存放地方,好了給個例子:

String topic = “test”;  //        String zkRoot = “/kafkastorm”; //        String spoutId = “id”; //讀取的status會被存在,/kafkastorm/id下面,所以id類似consumer group                BrokerHosts brokerHosts = new ZkHosts("10.1.110.24:2181,10.1.110.22:2181"); // 這裡使用預設的/brokers        SpoutConfig spoutConfig = new SpoutConfig(brokerHosts, topic, zkRoot, spoutId);        spoutConfig.scheme = new SchemeAsMultiScheme(new StringScheme()); // 下一節介紹 scheme                /*spoutConfig.zkServers = new ArrayList<String>(){{ //只有在local模式下需要記錄讀取狀態時,才需要設定            add("10.118.136.107");        }};        spoutConfig.zkPort = 2181;*/                spoutConfig.forceFromStart = true;         spoutConfig.startOffsetTime = -1;//從最新的開始消費         // spoutConfig.metricsTimeBucketSizeInSecs = 6;        builder.setSpout(SqlCollectorTopologyDef.KAFKA_SPOUT_NAME, new KafkaSpout(spoutConfig), 1);

這裡就成功建了一個KafkaSpout,如果項目運行成功的話,

可以到zk master上看下相關資訊,

./bin/zkCli.sh -server 10.1.110.24:2181



而對於StaticHosts來說,看官方解釋:

StaticHosts

This is an alternative implementation where broker -> partition information is static. In order to construct an instance of this class you need to first construct an instance of GlobalPartitionInformation.

    Broker brokerForPartition0 = new Broker("localhost");//localhost:9092    Broker brokerForPartition1 = new Broker("localhost", 9092);//localhost:9092 but we specified the port explicitly    Broker brokerForPartition2 = new Broker("localhost:9092");//localhost:9092 specified as one string.    GlobalPartitionInformation partitionInfo = new GlobalPartitionInformation();    partitionInfo.addPartition(0, brokerForPartition0);//mapping form partition 0 to brokerForPartition0    partitionInfo.addPartition(1, brokerForPartition1);//mapping form partition 1 to brokerForPartition1    partitionInfo.addPartition(2, brokerForPartition2);//mapping form partition 2 to brokerForPartition2    StaticHosts hosts = new StaticHosts(partitionInfo);
個人認為是需要開發人員,自己知道partition與broker之間的對應關係,正確關聯起來。而storm-kafka 0.9.0.1的版本是,不需要指定,我只需要傳入zkServer list,partition總數,由kafkautil利用兩個for(遍曆所有broker和partition)迴圈,臨時產生Consumer去串連消費一下試試,如果有資料,那麼就把partitionId和brokerHost關係存到Map中去。可想而知0.9.3-rc1為什麼要改成這樣了。如果該broker沒有該partition資訊,後果會怎樣???筆者沒有測試過,有測試過的請留言,說一下情況。Reference

http://www.cnblogs.com/fxjwind/p/3808346.html

(三)storm-kafka源碼走讀之如何構建一個KafkaSpout

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.