相互認知org.apache.cassandra.service.StorageServiceinitServer304 initialized = true;305 isClientMode = false;306 storageMetadata_ = SystemTable.initMetadata();307308 // be certain that the recorded clustername matches what the user specified309 if (!(Arrays.equals(storageMetadata_.getClusterName(),DatabaseDescriptor.getClusterName().getBytes())))310 {311 logger_.error("ClusterName mismatch: " + new String(storageMetadata_.getClusterName()) + " != " +312 DatabaseDescriptor.getClusterName());313 System.exit(3);314 }315316 DatabaseDescriptor.createAllDirectories();最初に自分自身の初期化を行う。クラスターネーム、キースペース、トークンなどメタ情報取得など
16.
ゴシップ開始org.apache.cassandra.service.StorageService327 logger_.info("Starting up server gossip");328329 // have to start the gossip service before we can see any info on other nodes. this is necessary330 // for bootstrap to get the load info it needs.331 // (we won't be part of the storage ring though until we add a nodeId to our state, below.)332 Gossiper.instance.register(this);333Gossiper.instance.start(FBUtilities.getLocalAddress(), storageMetadata_.getGeneration()); // needed for node-ring gathering.「start」の最初にローカルのアドレスを取得。(FBUtilities.getLocalAddress)私たちが、他のノードの情報を見ることができる前にゴシップサービスは始めなければなりません。これは、「bootstrap」が必要とする負荷の情報を得る為に必要です。もっとも、私たちは「nodeid」を私たちのstateに追加するまでストレージ・リングの一部でなくなるでしょう。
17.
ゴシップ開始2org.apache.cassandra.gms.Gossiper838 public void start(InetAddresslocalEndPoint, intgenerationNbr)839 {840 localEndPoint_ = localEndPoint;841 /* Get the seeds from the config and initialize them. */842 Set<InetAddress> seedHosts = DatabaseDescriptor.getSeeds();843 for (InetAddress seed : seedHosts)844 {845 if (seed.equals(localEndPoint))846 continue;847 seeds_.add(seed);848 }Seedsより自分以外のIPを取得
18.
ゴシップ開始3org.apache.cassandra.gms.Gossiper351 /* initialize the heartbeat state for this localEndPoint */352 EndPointStatelocalState = endPointStateMap_.get(localEndPoint_);353 if ( localState == null )354 {355 HeartBeatStatehbState = new HeartBeatState(generationNbr);356 localState = new EndPointState(hbState);357 localState.isAlive(true);358 localState.isAGossiper(true);359 endPointStateMap_.put(localEndPoint_, localState);360 }自分のハートビートステータスを取得
19.
ゴシップ開始4org.apache.cassandra.gms.Gossiper361 /* starts a timer thread */362 gossipTimer_.schedule( new GossipTimerTask(), Gossiper.intervalInMillis_, Gossiper.intervalInMillis_);GossipTimerTask起動! public final static intintervalInMillis_ = 1000;というところで1000ミリ秒間隔でタイマー起動
20.
GossipTimerTaskorg.apache.cassandra.gms.Gossiperprivate class GossipTimerTaskextends TimerTask{ public void run() { try {MessagingService.instance.waitUntilListening(); synchronized( Gossiper.instance ) {endPointStateMap_.get(localEndPoint_).getHeartBeatState().updateHeartBeat(); List<GossipDigest> gDigests = new ArrayList<GossipDigest>();Gossiper.instance.makeRandomGossipDigest(gDigests); if ( gDigests.size() > 0 ) { Message message = makeGossipDigestSynMessage(gDigests);booleangossipedToSeed = doGossipToLiveMember(message);doGossipToUnreachableMember(message); if (!gossipedToSeed || liveEndpoints_.size() < seeds_.size())doGossipToSeed(message); if (logger_.isTraceEnabled())logger_.trace("Performing status check ...");doStatusCheck(); } } } catch (Exception e) { throw new RuntimeException(e); } }}GossipTimerTask親abstractクラスにてRunnableのインターフェースを実装。Runにてスレッド開始1000ミリ秒ごとにハートビートを交換。