def measure(argv): """Measure throughput in 15s""" # Parse parameters quorumSize1, quorumSize2, drop_ratio, selfAddr, partners = parseParams( argv) maxCommandsQueueSize = int(0.9 * SyncObjConf().commandsQueueSize / len(partners)) # Init a TestObj counter1 = ReplCounter() obj = SyncObj(selfAddr, partners, quorumSize1, quorumSize2, drop_ratio, consumers=[counter1]) while obj._getLeader() is None: time.sleep(0.5) time.sleep(4.0) count = 0 startTime = time.time() while time.time() - startTime < 10.0: counter1.inc() while time.time() - startTime < 40.0: counter1.inc() count += 1 print(obj.getStatus()['raft_term']) time.sleep(4.0) return count
def __initDistributedDict(self): rr_raft = ReplDict() config = SyncObjConf(appendEntriesUseBatch=True) syncObj = SyncObj(self.__node, self.__other_nodes, consumers=[rr_raft], conf=config) if not self.__silent: print "Initializing Raft..." while not syncObj.isReady(): continue if not self.__silent: print "Raft initialized!" return rr_raft
def __init__(self, my_addr, partners_addrs): self.log = {} self.al = ReplDict() #adjacency list self.lock = threading.Lock() self.rwlock = RWLock() self.interfaces = dict() #for talking with other servers syncObj = SyncObj(my_addr, partners_addrs, consumers=[self.al])
def start(self): logging.info('Start') self.nodes = Nodes() self.worker_q = queue.Queue() self.worker = threading.Thread(target=node_worker, args=(self, self._addr, 'slave', self.worker_q)) self.worker.daemon = True self._syncObjConf = SyncObjConf( onReady=lambda: self._onReady(), onStateChanged=lambda os, ns: self._stateChanged(os, ns)) self._syncObj = SyncObj( f'{self._addr}:{self._raft_port}', [f'{p}:{self._raft_port}' for p in self._peers], consumers=[self.logs, self.nodes], conf=self._syncObjConf)
async def setup_raft(raft_addr, cluster): """初始化/连接 Raft 集群 :param raft_addr: 本节点用于Raft集群通信的地址;为None时表示加入现有集群,本节点地址由本节点第一位用户输入 :param cluster: 集群节点地址列表;为None时表示加入现有集群,集群节点地址由本节点第一位用户输入 :return: 本节点Raft集群通信地址 """ global raft_server mode = 'init' if not raft_addr: # raft_addr 为None时,表示加入Raft集群 mode = 'join' currhost = session.get_info().origin.rsplit(":", 1)[0].split("//", 1)[-1] data = await input_group("加入Raft集群", [ input("当前节点的Raft通信端口", name="port"), input("当前节点的Host地址", name="host", value=currhost, help_text="其他节点需要可以通过此Host与当前节点通信"), input("集群节点地址", name="remote", placeholder='host:ip', help_text="填入集群中任一节点的地址即可") ]) raft_addr = '%s:%s' % (data['host'], data['port']) cluster = join_cluster(raft_addr, data['remote']) if not cluster: put_markdown("### 加入集群失败") return raft_port = raft_addr.split(":", 1)[-1] cfg = SyncObjConf(dynamicMembershipChange=True, fullDumpFile=raft_addr + '.data', onStateChanged=partial(onStateChanged, node=raft_addr), bindAddress="0.0.0.0:%s" % raft_port) raft_server = SyncObj( raft_addr, cluster, consumers=[chat_msgs, node_user_cnt, node_webui_addr], conf=cfg) if mode == 'join': send_msg(ADMIN_USER, '节点`%s`加入集群' % raft_addr, instant_output=False) return raft_addr
import time from pysyncobj import SyncObj from pysyncobj.batteries import ReplCounter, ReplDict dict1 = ReplDict() #syncObj = SyncObj('localhost:4321', ['localhost:4322', 'localhost:4323'], consumers=[dict1]) syncObj = SyncObj('localhost:4321', [], consumers=[dict1]) print dir(syncObj) while True: if syncObj.isReady(): print dict1.get('key') time.sleep(1)
class Cluster: def __init__(self, config, addr, peers): self._addr = addr self._peers = peers self.logs = Logs() self._raft_port = config['network']['raft_port'] self.config = config def set_local_logs(self, local_logs): self._local_logs = local_logs def start(self): logging.info('Start') self.nodes = Nodes() self.worker_q = queue.Queue() self.worker = threading.Thread(target=node_worker, args=(self, self._addr, 'slave', self.worker_q)) self.worker.daemon = True self._syncObjConf = SyncObjConf( onReady=lambda: self._onReady(), onStateChanged=lambda os, ns: self._stateChanged(os, ns)) self._syncObj = SyncObj( f'{self._addr}:{self._raft_port}', [f'{p}:{self._raft_port}' for p in self._peers], consumers=[self.logs, self.nodes], conf=self._syncObjConf) def local_msg(self, msg): self.worker_q.put(msg) def _onReady(self): logging.info(f'Raft ready...') self.worker.start() self.sync_logs() def sync_logs(self): if self._local_logs.logs: logging.info('sending info about local logs') # it still doesn't support log replicas... for log in self._local_logs.logs: if log in self.logs.get_logs(): continue logging.warning(log) self.logs.add_log(log, { 'replicas': [self._addr], 'state': LogState.SHOULD_REPLICATE }) def _stateChanged(self, oldState, newState): if newState == RaftState.LEADER: self.worker_q.put('leader') state = 'leader' elif newState == RaftState.FOLLOWER: self.worker_q.put('follower') state = 'follower' else: state = 'candidate' logging.info(f'changed Raft role to: {state}') def state(self): return { 'logs': copy.copy(self.logs.get_logs()), 'nodes': copy.copy(self.nodes.get_nodes()) } def healthy(self): return self._syncObj.getStatus()['leader'] is not None
from flask import Flask, request from pysyncobj import SyncObj, replicated from pysyncobj.batteries import ReplCounter import json import os import socket RAFT_PORT = "4321" MY_NODE_NUM = int(os.environ["MY_NODE_NUM"]) TOTAL_NODES = int(os.environ["TOTAL_NODES"]) ADDRESSES = ["node" + str(n) + ":" + RAFT_PORT for n in range(TOTAL_NODES)] MY_ADDRESS = ADDRESSES[MY_NODE_NUM] PEER_ADDRESSES = [ADDRESSES[i] for i in range(TOTAL_NODES) if i != MY_NODE_NUM] counter = ReplCounter() sync = SyncObj(MY_ADDRESS, PEER_ADDRESSES, consumers=[counter]) sync.waitBinded() app = Flask(__name__) @app.route("/inc") def inc(): return json.dumps(counter.inc(sync=True)) @app.route("/status") def status(): return json.dumps(sync.getStatus())
def __init__(self, ip, port, selfnode, othernodes): super(GameServer, self).__init__(ip, port, GameServerEntity) self.data = ReplCounter() self.syncObj = SyncObj(selfnode, othernodes, consumers=[self.data, ])
def create(res, err, label): print("Created a queue for label {}".format(label), res, err) if __name__ == '__main__': if len(sys.argv) < 3: print('Usage: %s self_port partner1_port partner2_port ...' % sys.argv[0]) sys.exit(-1) port = int(sys.argv[1]) partners = ['localhost:%d' % int(p) for p in sys.argv[2:]] q = ReplList() sync = SyncObj('localhost:%d' % port, partners, consumers=[q]) # for item in range(5): # q.append(item) while True: q.insert(0, 10) print q.rawData() time.sleep(10) # q.remove(4) # print q.rawData() # q = FTQueue('localhost:{}'.format(port),partners) # num_clients = 3 # label = 0 # # while num_clients > 0: # # ID = q.qCreate(label)
def main(): # log everything to stderr because compose containers for some reason aren't logging stdout logging.basicConfig(level=logging.DEBUG, filename='/proc/self/fd/2', filemode='w') peers = None if "NBDD_PEERS" not in os.environ else os.environ[ "NBDD_PEERS"].split(",") hostname = os.environ.get("NBDD_HOSTNAME") # contains all blocks for all devices as a contiguous list of bytes blocks = [] # a list of all devices so we know the starting offset of a given device in `blocks` # (all devices are fixed size) volumes = [] tracer = jaeger_client.Config( config={ 'sampler': { 'type': 'const', 'param': 1, }, 'logging': True, }, service_name='nbd', ).initialize_tracer() if peers: LocalState.f = open('/tmp/blocks', 'r+b') write_cache = LoglessCache() LocalState.write_sharer = WriteSharer(peers, write_cache) _thread.start_new_thread(LocalState.write_sharer.listen_for_asks, ()) LocalState.lock = threading.Lock() LocalState.hostname = hostname LocalState.write_count = 0 blocks = ReplFile() volumes = ReplList() health_counter = ReplCounter() HealthHandler.counter = health_counter self_address = "{}:2001".format(hostname) peer_addresses = ["{}:2001".format(peer) for peer in peers] syncObj = SyncObj(self_address, peer_addresses, consumers=[blocks, volumes, health_counter]) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('0.0.0.0', 2000)) sock.setblocking(True) sock.listen(1) httpd = HTTPServer(('0.0.0.0', 8080), HealthHandler) _thread.start_new_thread(httpd.serve_forever, ()) # Prototype will listen to one client at a time # -- can be made concurrent without much extra work logging.info("NBD Server '{}' Starting with peers {}...".format( hostname, peers)) while True: cxn, client = sock.accept() logging.info("Connection accepted from client {}".format(client)) _thread.start_new_thread(handle_cxn, (cxn, blocks, volumes, tracer)) logging.info( "Connection closed by client {} -- listening for next client". format(client))