1、主库配置(192.168.1.200)
a、my.cnf中【mysqld】节配置
server-id = 1 //master服务ID,必须唯一*
log-bin = mysql-bin //同步日志文件,必须打开*
b、登录mysql创建同步账户并授予权限:
grant replication slave,reload,super on *.* to myslave@'192.168.1.201' identified by '123456';
2、slave配置(192.168.1.201)
a、my.cnf中【mysqld】节
server-id = 2 //master服务ID,必须唯一*
log-bin = mysql-bin //同步日志文件,必须打开*
master-host = 192.168.1.200 //主库地址*
master-user = myslave //同步的用户名*
master-password = 123456 //同步的密码*
master-port = 3306 //主库端口*
master-connect-retry=60 //同步失败重连时间
replicate-do-db = testslave //执行同步的数据库*
以下配置为可选配置,根据实际需求调整
replicate-ignore-db = mysql //不同步的数据库
replicate-do-table = user //执行同步的表
replicate-ignore-table = city //不同步的表
replicate-wild-do-table = testslave.a% //执行同步的多个表
replicate-wild_ignore-table = mysql.b% //不同步的多个表
3、重新启动主、从库
4、同步数据库
a、登录主库并执行:
mysql>flush tables with read lock;
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000008 | 106 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
//此处需要记录下来同步的开始位置106
再打开一个窗口,将主库的数据文件拷贝到从库中:
scp testslave/* root@192.168.1.201:/usr/mysql/var/testslave/
拷贝完成之后,返回前一个窗口解锁数据库只读。
mysql>unlock tables;
b、登录从库mysql:
mysql>flush tables;
mysql>stop slave;
mysql>CHANGE MASTER TO MASTER_HOST='192.168.1.200', MASTER_PORT=3306, MASTER_USER='myslave',
MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000008', MASTER_LOG_POS=106;
mysql>start slave;
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.200
Master_User: myslave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000008
Read_Master_Log_Pos: 106
Relay_Log_File: ccone2-relay-bin.000002
Relay_Log_Pos: 251
Relay_Master_Log_File: mysql-bin.000008
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: ccone
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 106
Relay_Log_Space: 407
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
1 row in set (0.00 sec)
ERROR:
No query specified
查看Slave_IO_Running: Yes 和Slave_SQL_Running: Yes 2个都为yes则证明主从同步正常,
否则证明同步有问题,可查看日志文件修复。
5、如果做双向同步,则可在此基础上将主从库再反向配置即可实现。
已有 0 人发表留言,猛击->>这里<<-参与讨论
ITeye推荐
- —软件人才免语言低担保 赴美带薪读研!—
环境
JBoss 6.0 + MyEclipse 8.6 + MySQL 5.1 + Struts 2.3 + EJB 3.0
问题
启动JBoss出现如下异常:Dispatcher initialization failedjava.lang.RuntimeException: java.lang.reflect.InvocationTargetException
解决
核对Struts版本和web.xml过滤器配置是否一致。
struts2版本是2.1以前
web.xml过滤器配置
<web-app> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
如果struts2 版本是2.1以上
web.xml过滤器配置配置
<web-app> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
参考资料
http://blog.csdn.net/helifengwell/article/details/5855144
http://rani.iteye.com/blog/794360
@Wentasy 博文仅供参考,欢迎大家来访。如有错误之处,希望批评指正。原创博文如需转载请注明出处,谢谢 :) [CSDN博客]
Map-Reduce的过程首先是由客户端提交一个任务开始的。
提交任务主要是通过JobClient.runJob(JobConf)静态函数实现的:
public static RunningJob runJob(JobConf job) throws IOException {
//首先生成一个JobClient对象
JobClient jc = new JobClient(job);
……
//调用submitJob来提交一个任务
running = jc.submitJob(job);
JobID jobId = running.getID();
……
while (true) {
//while循环中不断得到此任务的状态,并打印到客户端console中
}
return running;
}
其中JobClient的submitJob函数实现如下:
public RunningJob submitJob(JobConf job) throws FileNotFoundException,
InvalidJobConfException, IOException {
//从JobTracker得到当前任务的id
JobID jobId = jobSubmitClient.getNewJobId();
//准备将任务运行所需要的要素写入HDFS:
//任务运行程序所在的jar封装成job.jar
//任务所要处理的input split信息写入job.split
//任务运行的配置项汇总写入job.xml
Path submitJobDir = new Path(getSystemDir(), jobId.toString());
Path submitJarFile = new Path(submitJobDir, "job.jar");
Path submitSplitFile = new Path(submitJobDir, "job.split");
//此处将-libjars命令行指定的jar上传至HDFS
configureCommandLineOptions(job, submitJobDir, submitJarFile);
Path submitJobFile = new Path(submitJobDir, "job.xml");
……
//通过input format的格式获得相应的input split,默认类型为FileSplit
InputSplit[] splits =
job.getInputFormat().getSplits(job, job.getNumMapTasks());
// 生成一个写入流,将input split得信息写入job.split文件
FSDataOutputStream out = FileSystem.create(fs,
submitSplitFile, new FsPermission(JOB_FILE_PERMISSION));
try {
//写入job.split文件的信息包括:split文件头,split文件版本号,split的个数,接着依次写入每一个input split的信息。
//对于每一个input split写入:split类型名(默认FileSplit),split的大小,split的内容(对于FileSplit,写入文件名,此split在文件中的起始位置),split的location信息(即在那个DataNode上)。
writeSplitsFile(splits, out);
} finally {
out.close();
}
job.set("mapred.job.split.file", submitSplitFile.toString());
//根据split的个数设定map task的个数
job.setNumMapTasks(splits.length);
// 写入job的配置信息入job.xml文件
out = FileSystem.create(fs, submitJobFile,
new FsPermission(JOB_FILE_PERMISSION));
try {
job.writeXml(out);
} finally {
out.close();
}
//真正的调用JobTracker来提交任务
JobStatus status = jobSubmitClient.submitJob(jobId);
……
}
二、JobTracker
JobTracker作为一个单独的JVM运行,其运行的main函数主要调用有下面两部分:
- 调用静态函数startTracker(new JobConf())创建一个JobTracker对象
- 调用JobTracker.offerService()函数提供服务
在JobTracker的构造函数中,会生成一个taskScheduler成员变量,来进行Job的调度,默认为JobQueueTaskScheduler,也即按照FIFO的方式调度任务。
在offerService函数中,则调用taskScheduler.start(),在这个函数中,为JobTracker(也即taskScheduler的taskTrackerManager)注册了两个Listener:
- JobQueueJobInProgressListener jobQueueJobInProgressListener用于监控job的运行状态
- EagerTaskInitializationListener eagerTaskInitializationListener用于对Job进行初始化
EagerTaskInitializationListener中有一个线程JobInitThread,不断得到jobInitQueue中的JobInProgress对象,调用JobInProgress对象的initTasks函数对任务进行初始化操作。
在上一节中,客户端调用了JobTracker.submitJob函数,此函数首先生成一个JobInProgress对象,然后调用addJob函数,其中有如下的逻辑:
synchronized (jobs) {
synchronized (taskScheduler) {
jobs.put(job.getProfile().getJobID(), job);
//对JobTracker的每一个listener都调用jobAdded函数
for (JobInProgressListener listener : jobInProgressListeners) {
listener.jobAdded(job);
}
}
}
EagerTaskInitializationListener的jobAdded函数就是向jobInitQueue中添加一个JobInProgress对象,于是自然触发了此Job的初始化操作,由JobInProgress得initTasks函数完成:
public synchronized void initTasks() throws IOException {
……
//从HDFS中读取job.split文件从而生成input splits
String jobFile = profile.getJobFile();
Path sysDir = new Path(this.jobtracker.getSystemDir());
FileSystem fs = sysDir.getFileSystem(conf);
DataInputStream splitFile =
fs.open(new Path(conf.get("mapred.job.split.file")));
JobClient.RawSplit[] splits;
try {
splits = JobClient.readSplitFile(splitFile);
} finally {
splitFile.close();
}
//map task的个数就是input split的个数
numMapTasks = splits.length;
//为每个map tasks生成一个TaskInProgress来处理一个input split
maps = new TaskInProgress[numMapTasks];
for(int i=0; i < numMapTasks; ++i) {
inputLength += splits[i].getDataLength();
maps[i] = new TaskInProgress(jobId, jobFile,
splits[i],
jobtracker, conf, this, i);
}
//对于map task,将其放入nonRunningMapCache,是一个Map<Node, List<TaskInProgress>>,也即对于map task来讲,其将会被分配到其input split所在的Node上。nonRunningMapCache将在JobTracker向TaskTracker分配map task的时候使用。
if (numMapTasks > 0) {
nonRunningMapCache = createCache(splits, maxLevel);
}
//创建reduce task
this.reduces = new TaskInProgress[numReduceTasks];
for (int i = 0; i < numReduceTasks; i++) {
reduces[i] = new TaskInProgress(jobId, jobFile,
numMapTasks, i,
jobtracker, conf, this);
//reduce task放入nonRunningReduces,其将在JobTracker向TaskTracker分配reduce task的时候使用。
nonRunningReduces.add(reduces[i]);
}
//创建两个cleanup task,一个用来清理map,一个用来清理reduce.
cleanup = new TaskInProgress[2];
cleanup[0] = new TaskInProgress(jobId, jobFile, splits[0],
jobtracker, conf, this, numMapTasks);
cleanup[0].setJobCleanupTask();
cleanup[1] = new TaskInPro