kv-store/
├── bin/ # 可执行文件目录
│ ├── start-server.sh # 服务端启动脚本
│ └── start-client.sh # 客户端启动脚本
├── conf/ # 配置文件目录
│ ├── node1/ # 节点1配置
│ │ ├── server.properties # 服务器配置
│ │ └── logback.xml # 日志配置
│ ├── node2/
│ │ ├── server.properties
│ │ └── logback.xml
│ └── node3/
│ ├── server.properties
│ └── logback.xml
├── lib/ # 依赖库目录
│ ├── kv-server-1.0.jar
│ ├── kv-client-1.0.jar
│ ├── kv-common-1.0.jar
│ └── kv-thrift-1.0.jar
├── data/ # 数据目录
│ ├── node1/
│ │ ├── rocksdb/ # RocksDB数据文件
│ │ └── raft-log/ # Raft日志文件
│ ├── node2/
│ │ ├── rocksdb/
│ │ └── raft-log/
│ └── node3/
│ ├── rocksdb/
│ └── raft-log/
└── logs/ # 日志目录
├── node1/
├── node2/
└── node3/
2.1 节点1配置(conf/node1/server.properties)
# 基本配置
node.id =node1
node.name =Node-1
# 服务器配置
server.host =127.0.0.1
server.port =8090
server.max-connections =100
# 集群配置
cluster.enabled =true
cluster.peers =node1:127.0.0.1:8090,node2:127.0.0.1:8091,node3:127.0.0.1:8092
cluster.replication-factor =2
cluster.election-timeout-ms =5000
cluster.heartbeat-interval-ms =1000
# 存储配置
storage.rocksdb.path =/Users/jerry/data/node1/rocksdb
storage.raft.log-path =/Users/jerry/data/node1/raft-log
storage.max-memory-mb =512
# 线程池配置
thread.pool.min =4
thread.pool.max =32
# 日志配置
log.path =/Users/jerry/logs/node1
log.level =INFO
2.2 节点2配置(conf/node2/server.properties)
node.id =node2
node.name =Node-2
server.host =127.0.0.1
server.port =8091
# 其他配置相同,修改相应路径
storage.rocksdb.path =/Users/jerry/data/node2/rocksdb
storage.raft.log-path =/Users/jerry/data/node2/raft-log
log.path =/Users/jerry/logs/node2
2.3 节点3配置(conf/node3/server.properties)
node.id =node3
node.name =Node-3
server.host =127.0.0.1
server.port =8092
# 其他配置相同,修改相应路径
storage.rocksdb.path =/Users/jerry/data/node3/rocksdb
storage.raft.log-path =/Users/jerry/data/node3/raft-log
log.path =/Users/jerry/logs/node3
2.4 日志配置(conf/nodeX/logback.xml)
<?xml version =" 1.0" encoding =" UTF-8" ?>
<configuration >
<property name =" LOG_PATH" value =" logs/node1" />
<appender name =" CONSOLE" class =" ch.qos.logback.core.ConsoleAppender" >
<encoder >
<pattern >%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern >
</encoder >
</appender >
<appender name =" FILE" class =" ch.qos.logback.core.rolling.RollingFileAppender" >
<file >${LOG_PATH}/server.log</file >
<rollingPolicy class =" ch.qos.logback.core.rolling.TimeBasedRollingPolicy" >
<fileNamePattern >${LOG_PATH}/server.%d{yyyy-MM-dd}.log</fileNamePattern >
<maxHistory >30</maxHistory >
</rollingPolicy >
<encoder >
<pattern >%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern >
</encoder >
</appender >
<root level =" INFO" >
<appender-ref ref =" CONSOLE" />
<appender-ref ref =" FILE" />
</root >
</configuration >
3.1 服务端启动脚本(bin/start-server.sh)
#! /bin/bash
if [ $# -ne 2 ]; then
echo " Usage: $0 <node-id> <config-path>"
exit 1
fi
NODE_ID=$1
CONFIG_PATH=$2
# 设置CLASSPATH
CLASSPATH=" lib/*"
# 设置JVM参数
JVM_OPTS=" -Xms512m -Xmx1024m -XX:+UseG1GC"
# 启动服务器
java $JVM_OPTS -cp $CLASSPATH \
-Dlogback.configurationFile=$CONFIG_PATH /logback.xml \
com.kv.server.KVServer \
$CONFIG_PATH /server.properties
3.2 客户端启动脚本(bin/start-client.sh)
#! /bin/bash
if [ $# -ne 2 ]; then
echo " Usage: $0 <host> <port>"
exit 1
fi
HOST=$1
PORT=$2
# 设置CLASSPATH
CLASSPATH=" lib/*"
# 启动客户端
java -cp $CLASSPATH com.kv.client.KVCommandClient $HOST $PORT
创建必要的目录:
mkdir -p /Users/jerry/bin /Users/jerry/conf /Users/jerry/lib /Users/jerry/data /Users/jerry/logs
mkdir -p /Users/jerry/conf/{node1,node2,node3,node4}
mkdir -p /Users/jerry/data/{node1,node2,node3,node4}/{rocksdb-data,raft-log}
mkdir -p /Users/jerry/logs/{node1,node2,node3,node4}
# 在项目根目录下
mkdir -p /Users/jerry/data/node1/raft-log
mkdir -p /Users/jerry/data/node2/raft-log
mkdir -p /Users/jerry/data/node3/raft-log
mkdir -p /Users/jerry/data/node4/raft-log
复制JAR包到lib目录:
cp /Users/jerry/IdeaProjects/LightKV/kv-server/target/kv-server-1.0-SNAPSHOT-jar-with-dependencies.jar /Users/jerry/lib/kv-server-1.0-SNAPSHOT.jar
cp /Users/jerry/IdeaProjects/LightKV/kv-client/target/kv-client-1.0-SNAPSHOT.jar /Users/jerry/lib/
cp /Users/jerry/IdeaProjects/LightKV/kv-client/target/kv-client-1.0-SNAPSHOT.jar /Users/jerry/lib/
cp /Users/jerry/IdeaProjects/LightKV/kv-server/target/kv-server-1.0-SNAPSHOT-jar-with-dependencies.jar /Users/jerry/lib/kv-server-1.0-SNAPSHOT.jar
复制配置文件:
# 为每个节点创建配置
cp /Users/jerry/IdeaProjects/LightKV/kv-store/conf/node1/server.properties /Users/jerry/conf/node1/
cp /Users/jerry/IdeaProjects/LightKV/kv-store/conf/node2/server.properties /Users/jerry/conf/node2/
cp /Users/jerry/IdeaProjects/LightKV/kv-store/conf/node3/server.properties /Users/jerry/conf/node3/
# 修改各个节点的配置
cp /Users/jerry/IdeaProjects/LightKV/kv-store/bin/start-client.sh /Users/jerry/bin
cp /Users/jerry/IdeaProjects/LightKV/kv-store/bin/start-server.sh /Users/jerry/bin
# 复制日志配置
# cp logback.xml /Users/jerry/conf/node{1,2,3}/
cp /Users/jerry/IdeaProjects/LightKV/kv-store/bin/start-client.sh /Users/jerry/bin
cp /Users/jerry/IdeaProjects/LightKV/kv-store/bin/start-server.sh /Users/jerry/bin
设置执行权限:
chmod +x /Users/jerry/bin/* .sh
启动节点1:
/Users/jerry/bin/start-server.sh /Users/jerry/IdeaProjects/LightKV/kv-store/conf/node1
启动节点2:
/Users/jerry/bin/start-server.sh /Users/jerry/IdeaProjects/LightKV/kv-store/conf/node2
启动节点3:
/Users/jerry/bin/start-server.sh /Users/jerry/IdeaProjects/LightKV/kv-store/conf/node3
启动客户端:
/Users/jerry/bin/start-client.sh localhost 18091