OneCoder


  • 首页

  • 归档

  • 标签

  • 关于

  • 搜索

CentOS下 PostgreSQL部署记录

发表于 2013-08-20

MySQL License收费的问题越来越现实了。PostgreSQL成了最好的替代方案。

部署环境:CentOS6.3 x64。PostgreSQL版本:9.2.4-1。

CentOS的Develop包模式行可能已经带了PostgreSQL数据库,不过版本较老,这里还是要全新部署一个。官网提供了很多的部署方式,这里笔者选择的是命令行交互的离线安装包的方式,因为可以脱离网络和操作系统UI进行安装,比较贴近生产环境。

离线包下载地址:

  • http://community.openscg.com/se/postgresql/packages.jsp

下载好对应操作系统的包,赋予执行权限,执行即可完成安装。安装期间会交互的让你设置一些默认的存放目录,如果没有特殊要求,默认回车即可。

安装很快即可完成。

启动数据库

不能使用root用户启动,需要使用安装时新创建的用户,默认为postgres。

bin>postgres -D data

-D 为指定配置文件和数据存放目录。该目录须存在且包含postgres.conf配置文件。按照上面的方式安装后,只要指定为安装目录下的data文件夹即可。

如果不存在,则需要初始化该目录。

>initdb -D 目录

如果需要远程连接访问该数据库,需要修改pg_hba.conf文件,给指定的主机和ip开发访问权限。其实影响访问的还有postgresql.conf中的配置,不过默认是开放了权限的。

启动后可通过

>psql

客户端连接到数据库,查看数据库信息。具体命令可通过help查看。

阅读全文 »

Mac OS下 Redis2.6.14部署记录

发表于 2013-08-17

部署一个Redis作为缓存进行验证,记录部署过程。

官网:

  • http://redis.io/

目前最近稳定版为2.6.14。解压,进入目录。按照README文件的指引进行编译和验证。

在解压后的根目录执行

$>make

执行后,可以通过

$>make test

进行验证,基本看到的就是一堆OK。

编译完成,启动Redis服务。进入src目录。

$>cd src
$>./redis-server

至此,redis服务就启动好了,如果你想把redis相关的命令安装到/usr/local/bin下,可以执行

$>make install

启动后,可以通过客户端命令验证服务是否正常运行。

至此,一个redis服务就部署完成了,如果想通过Java访问可以下载Jedis包,API非常简单。

阅读全文 »

CentOS下 Storm0.8.2 环境搭建记录

发表于 2013-08-12

Storm是Twitter开源的一个实时计算框架,它需要依赖Zookeeper,ZeroMQ;同时还需要你的系统环境中有Java和Python。所以整个搭建步骤如下:

1. 搭建Zookeeper集群。
2. 在控制节点机[ Nimbus ]和工作节点机[ Supervisor ]上安装相同的环境(ZeroMQ,JZMQ,Java,Python等)
3. 在控制节点机[ Nimbus ]和工作节点机[ Supervisor ]上安装Storm框架
4. 配置Storm,通过storm.yaml文件
5. 用命令启动Storm(需要分别启动Nimbus、Supervisor、ui)


1. 搭建Zookeeper

由于 storm并不用zookeeper来传递消息。所以zookeeper上的负载是非常低的,单个节点的zookeeper在大多数情况下都已经足够了,因此这里我们搭建单节点zookeeper。
下载最新版3.4.5:http://zookeeper.apache.org/releases.html#download
解压,在conf下增加配置文件zoo.cfg,可参考zoo-sample.cfg的配置修改,主要修改dataDir路径位置

启动zookeeper:

bin/zkServer.sh start

启动后,可通过:

bin/zkCli.sh -server 127.0.0.1:2181

验证启动状况和客户端连接状况

2、搭建ZeroMq2.1.7版:
官方提到,不要安装2.1.0版,如果使用2.1.7版遇到问题,可尝试降级到2.1.4版本。
下载:http://download.zeromq.org/
解压后,在目录中执行:

shell/>./configure


遇到uuid-dev的错误,说明需要安装uuid包:
在ubuntu下安装uuid-dev,在centos上安装:

yum install libuuid-devel.x86_64

然后再执行configure即可。
然后:

make
sudo make install

3、安装JZMQ
下载:https://codeload.github.com/nathanmarz/jzmq/zip/master
解压后执行:

./autogen.sh
./configure
make
sudo make install

./configure时会检查你的JAVA_HOME是否正确,不正确会报错,并提示。

4、安装Storm

下载:https://github.com/nathanmarz/storm
解压,配置storm.yaml配置文件。主要配置:
1) storm.zookeeper.servers: Storm集群使用的Zookeeper集群地址,其格式如下:

storm.zookeeper.servers:
  - "111.222.333.444"
  - "555.666.777.888"

如果Zookeeper集群使用的不是默认端口,那么还需要storm.zookeeper.port选项。
2) storm.local.dir: Nimbus和Supervisor进程用于存储少量状态,如jars、confs等的本地磁盘目录,需要提前创建该目录并给以足够的访问权限。然后在storm.yaml中配置该目录,如:

	storm.local.dir: "/home/admin/storm/workdir"

3) java.library.path: Storm使用的本地库(ZMQ和JZMQ)加载路径,默认为"/usr/local/lib:/opt/local/lib:/usr/lib",一般来说ZMQ和JZMQ默认安装在/usr/local/lib 下,因此不需要配置即可。
4) nimbus.host: Storm集群Nimbus机器地址,各个Supervisor工作节点需要知道哪个机器是Nimbus,以便下载Topologies的jars、confs等文件,如:
nimbus.host: "111.222.333.444"
5) supervisor.slots.ports: 对于每个Supervisor工作节点,需要配置该工作节点可以运行的worker数量。每个worker占用一个单独的端口用于接收消息,该配置选项即 用于定义哪些端口是可被worker使用的。默认情况下,每个节点上可运行4个workers,分别在6700、6701、6702和6703端口,如:

	supervisor.slots.ports:
	    - 6700
	    - 6701
	    - 6702
	    - 6703

启动Storm最后一步,启动Storm的所有后台进程。和Zookeeper一样,Storm也是快速失败(fail-fast)的系统,这样Storm才能在 任意时刻被停止,并且当进程重启后被正确地恢复执行。这也是为什么Storm不在进程内保存状态的原因,即使Nimbus或Supervisors被重 启,运行中的Topologies不会受到影响。
以下是启动Storm各个后台进程的方式:

1. Nimbus: 在Storm主控节点上运行"bin/storm nimbus >/dev/null 2>&1 &"启动Nimbus后台程序,并放到后台执行;
2. Supervisor: 在Storm各个工作节点上运行"bin/storm supervisor >/dev/null 2>&1 &"启动Supervisor后台程序,并放到后台执行;
3. UI: 在Storm主控节点上运行"bin/storm ui >/dev/null 2>&1 &"启动UI后台程序,并放到后台执行,启动后可以通过http://{nimbus host}:8080观察集群的worker资源使用情况、Topologies的运行状态等信息。

注意事项:

1. Storm后台进程被启动后,将在Storm安装部署目录下的logs/子目录下生成各个进程的日志文件。
2. 经测试,Storm UI必须和Storm Nimbus部署在同一台机器上,否则UI无法正常工作,因为UI进程会检查本机是否存在Nimbus链接。
3. 为了方便使用,可以将bin/storm加入到系统环境变量中。

至此,Storm集群已经部署、配置完毕,可以向集群提交拓扑运行了。
附:Storm的主要依赖:
Apache Zookeeper、ØMQ、JZMQ、Java 6和Python 2.6.6

阅读全文 »

JPPF-log4j远程日志管理

发表于 2013-07-17

利用JPPF进行并行计算,计算任务运行在远端节点上,那么如何收集运行在远端的任务日志,用于跟踪和分析呢?

JPPF框架对此也有封装,主要的实现思路是,通过自定义实现一个log4j的appender,对外提供JMX服务。客户端(监控端)实现一个监听器,监听远端日志,这样即可把远端日志采集到本地进行统一的管理。这对于我们收集和管理并行计算实时日志是非常有用的。具体看一下:

在没个执行任务的Node节点,修改log4j的配置,启用jppf提供的JmxAppender:
log4j-node.properties

log4j.appender.JMX=org.jppf.logging.log4j.JmxAppender
log4j.appender.JMX.layout=org.apache.log4j.PatternLayout
log4j.appender.JMX.layout.ConversionPattern=%d [%-5p][%c.%M(%L)]: %m\n

### set log levels - for more verbose logging change 'info' to 'debug' ###
#log4j.rootLogger=DEBUG, JPPF
log4j.rootLogger=INFO, JPPF, JMX

客户端代码如下:

/**
* @author lihzh
* @alia OneCoder
* @blog http://www.coderli.com
* @date 2013年7月17日 上午10:34:44
*/
public class RemoteLog {
     public static void main(String args[]) throws Exception {
            // get a JMX connection to the node MBean server
           JMXNodeConnectionWrapper jmxNode = new JMXNodeConnectionWrapper("localhost" ,
                     12001);
           jmxNode.connectAndWait(500000L);
            // get a proxy to the MBean
           JmxLogger nodeProxy = jmxNode.getProxy(JmxLogger.DEFAULT_MBEAN_NAME ,
                     JmxLogger. class);
            // use a handback object so we know where the log messages come from
           String source = "node   " + jmxNode.getHost() + ":" + jmxNode.getPort();
            // subbscribe to all notifications from the MBean
           NotificationListener listener = new MyLoggingHandler();
           nodeProxy.addNotificationListener(listener, null, source);
           String source167 = "node   " + jmxNode167.getHost() + ":" + jmxNode167.getPort();
     }
}

public class MyLoggingHandler implements NotificationListener {
            // handle the logging notifications
            public void handleNotification(Notification notification,
                     Object handback) {
                String message = notification.getMessage();
                String toDisplay = handback.toString() + ": " + message;
                System. out.println(toDisplay);
           }
     }

简单介绍下,就是通过ip和端口与需要监听的node节点建立jmx链接,然后讲自己事先的监听处理类MyLoggingHandler实例,注册到nodeProxy上。这样如果node端有日志出现,就会通知到监听端,可以进行自己的分类处理。试验一下,启动JPPF环境和启动监听,运行之前介绍的JPPF任务,可以看到在本地成功打印出任务日志信息,这样,并行计算任务分节点的日志收集处理也就很容易实现了。

阅读全文 »

JPPF并行计算框架类加载机制研究

发表于 2013-07-12

不算什么深入的研究,主要是了解下JPPF中类的加载和隔离机制。

JPPF中类的加载采用的是分布式类加载技术。这样既可在Node节点运行在node上并不存在的类。也就是类可以仅在用户的Client端存在。

如图,JPPF的class loader大致分三层。
System class loader是由JVM控制的加载器,用于启动node节点。在大多数JVM中是,该loader是java.net.URLClassloader的实例。
Server class loader是类AbstractJPPFClassloader的实现,提供了远程访问server端classpath中的类和其他资源的功能。该loader在node连接到server端的时候创建,断开连接的时候销毁。其父loader为System class loader。
Client class loader也是AbstractJPPFClassloader类的实现,提供了远程访问一个或多个客户端上的类和资源的功能。该loader在客户端提交任务的时候创建。一个node可能会持有很多client class loader。

JPPF的node节点仅持有一个与Server的连接,该连接被所有的loader共享,这样可以避免并发时潜在的的一致性,同步和冲突等问题。

Java的classloader是先从parent loader开始加载的饿,下图展示了node节点加载类的过程

 

node节点先从server节点请求class。如果server节点存在class,则直接加载返回。
如果class仅在client端存在,则会先访问server,server无,再通过server定位client,访问client端的class。

在JPPF框架里,每个client都有一个唯一的UUID,用于唯一标识该client。Node节点便可根据此UUID识别出当前classloader读取的是哪个client的class

每个Server也有唯一的UUID标识,这样就可以实现链式类加载:

需要注意的是,在这种情况下,node节点仍然只持有一个server classloader,仅连接跟它直接关联的server。

UUID与classloader
使用client端UUID,即可实现不同的client端在执行同一个任务的时候的classloader隔离,因为uuid不同,会使用不同的classloader加载类。不过,如果同一个UUID提交了两个不同版本的任务class,则有可能出现冲突和错误。    
你也可以手动指定client端的UUID,这样classloader即可重用。哪怕你重连client也可以重用同一个classloader。不过,此时随之而来的问题就是在客户端修改的版本可能不会在node端自动生效,不同的版本还可能造成冲突。这时,你可以重启node或者更换UUID使node重新加载class。

任务预部署
对于大任务,如果担心每次走网络效率低,根据上面介绍的classloader机制,自然想到可以预先将任务文件部署到server或者node节点。不过此时需要自己管理好部署的版本,所谓各有利弊。不过,如果任务版本稳定的话,建议采用此种方式。

classloader缓存池
为了避免加载过多的类造成内存溢出,JPPF在node端增加了classloader缓存池大小的设置,如果超过上限,则会销毁最老的classloader。

jppf.classloader.cache.size = n

本地缓存资源文件
当调用getResourceAsStream(),  getResource(),getResources() or getMultipleResources()方法的时候,class loader会缓存非类定义的文件至内存或者本地文件系统中。这样会避免再次请求该文件时候的网络访问,提高效率。你可以指定缓存在内存中还是文件系统中:

# either “file” (the default) or “memory“
jppf.resource.cache.storage = file

文件的保存路径当然也是可以配置的,默认是系统临时文件夹System.getProperty("java.io.tmpdir").:

jppf.resource.cache.dir = some_directory

JPPF server中的类缓存

JPPF的服务端会在内存中缓存被classloader加载进来的类和其他资。这样就可以避免与客户端的频繁的网络访问,从而提高执行速度。你也无需担心内存溢出的问题,因为这种缓存采用的是软引用,这样缓存的类就可以在必要的时候被JVM的垃圾回收机制回收。在一般情况,该缓存还是可以显著的提升效率的。

Class loader代理模型
JPPF默认采用的是”父优先“的类加载模型,也就是上面我们介绍的模型。上述模型虽然好用,但是类的加载顺序就相对固定,也就不能最大化的优化加载效率。因此,JPPF通过继承URLClassLoader,复写并开放addURL接口(jdk里是protected,JPPF为public),使得用户的自己开发任务可以直接调用该方法,形成对classloader的一种扩展。用户可调用addURL方法,指定自己想要加载类的地址。此时JPPF classloader的加载顺序会出现变化,从大的步骤看,会先查找指定的URL classpath:

* 从clientclassloader入手:代理到server的classloader
* server的classloader: 先仅查找用户指定的URL classpath
* 如果找到类,则结束查找
* 否则,回到client的classloader,也仅查找URL的classpath
* 如果找到,结束查找。

此书,如果仍未找到,则回到前面介绍的通过网络的查找顺序。
概括来说,就是如果URL优先的代理模型激活,则node会先从本地层级中查找URL指定的classpath,然后在网络上通过server查找。有三种指定代理模型的方式,最简单的就是直接配置在node节点的配置文件中:

  # possible values: parent | url, defaults to parent
  jppf.classloader.delegation = parent

下载文件

如我们之前的介绍的,我们可以通过addURL(URL)方法,动态指定加载类的URL地址,那么自然想到,我们可以通过先将文件下载到本地,然后指定URL地址,从而进行本地加载,以提到效率。在AbstractJPPFClassLoader类中,有方法:
public URL[] getMultipleResources(final String...names)
可以帮你同时下载多个文件到本地。

以上只是我了解到的JPPF中关于类加载部分的设计和实现。从已有掌握来看,JPPF考虑的还是非常全面周到的,隔离、效率、一致性都有考虑,应该说对并行计算来说,很有保障。

 

 

阅读全文 »

并行计算框架JPPF3.3.4试用

发表于 2013-07-10

先说一个挺有意思的事情,就在OneCoder准备记录试用过程的时候,给大家截图下载页面的时候,发现最新版本变成3.3.4了。于是,我也只好重新下载了:)

关于JPPF的介绍,可访问其官网:http://www.jppf.org
下载页面:http://www.jppf.org/downloads.php

想要运行JPPF并行计算任务,需要至少一个Node节点(执行任务的节点),一个driver节点(调度任务的节点),和本地调用节点

依次分别运行driver包里的startDriver.bat和node包里的startNode.bat启动driver和node
 

然后,开发jppf应用,JPPF在application-template包中提供了任务模版,只需参照文档稍作修改即可:

 public static void main(String args[]) {
           TaskFlowOne taskOne = new TaskFlowOne();
            try {
                 // create the JPPFClient. This constructor call causes JPPF to read
                 // the configuration file
                 // and connect with one or multiple JPPF drivers.
                 jppfClient = new JPPFClient();
                 // create a JPPF job
                JPPFJob job = new JPPFJob();
                 // give this job a readable unique id that we can use to monitor and
                 // manage it.
                job.setName( "Template Job Id");
                 // add a task to the job.
                job.addTask(taskOne);
                job.setBlocking( true);

                 // Submit the job and wait until the results are returned.
                 // The results are returned as a list of JPPFTask instances,
                 // in the same order as the one in which the tasks where initially
                 // added the job.
                List<JPPFTask> results = jppfClient.submit(job);
                JPPFTask jTask = results.get(0);
                System. out.println(jTask.getResult());
                 // process the results
                TaskFlowTwo taskTwo = new TaskFlowTwo();
                job.addTask(taskTwo);
                job.setBlocking( true);
                List<JPPFTask> resultsTow = jppfClient.submit(job);
                JPPFTask jTaskTow = resultsTow.get(1);
                System. out.println(jTaskTow.getResult());
           } catch (Exception e) {
                e.printStackTrace();
           } finally {
                 if ( jppfClient != null)
                      jppfClient.close();
           }
     }

一个并行计算的任务,就是一个JPPFJob,每个job含有多个task,task之间是并行执行的,如果有多个nod节点,会按照其负载均衡策略分配到多个node上执行。通过client提交(submit)job后,会返回执行结果,为一个JPPFTask列表,列表里包含你add到job中每个task及其运行结果,作为后续计算处理之用。任务调用支持阻塞和非阻塞。

admin-ui中还提供了对节点状态和资源占用,任务信息等监控,总体来说上手很快,很好用:


 

阅读全文 »

Hessian4.0.7+Spring3.2.2文件上传

发表于 2013-07-04

最近用Hessian4.0.7做文件上传,先给出自己做试验的样例代码,写在tomcat7下,采用servlet3.0,配置代码如下:

**
 * 基于Servlet3.0的,相当于以前<b>web.xml</b>配置文件的配置类
 * 
 * @author OneCoder
 * @Blog http://www.coderli.com
 * @date 2012-9-30 下午1:16:59
 */
publicclass DefaultWebApplicationInitializer implements
WebApplicationInitializer {

@Override
publicvoid onStartup(ServletContext appContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(DefaultAppConfig.class);

appContext.addListener(new ContextLoaderListener(rootContext));
ServletRegistration.Dynamic hessianServlet = appContext.addServlet("hessian", new HessianServlet());
hessianServlet.addMapping("/hessian");
hessianServlet.setInitParameter("service-class", HessianFileUploader.class.getName());
//ServletRegistration.Dynamic dispatcher = appContext.addServlet(
//"dispatcher", new DispatcherServlet(rootContext));
//dispatcher.setLoadOnStartup(1);
//dispatcher.addMapping("/");
//// Spring Security 过滤器配置
//FilterRegistration.Dynamic securityFilter = appContext.addFilter(
//"springSecurityFilterChain", DelegatingFilterProxy.class);
//securityFilter.addMappingForUrlPatterns(null, false, "/*");
}}

定义接口,并在服务端实现,Hessian4.0开始支持流作为参数传递,以前则采用byte[]方式传递:

public interface FileUploader {

void uplaodFile(String fileName,InputStream is);

}


public class HessianFileUploader implements FileUploader {

@Override
publicvoid uplaodFile(String fileName,InputStream is) {
try {
OutputStream out = new FileOutputStream("/Users/apple/Desktop/" + fileName);
int nLength = 0;
byte[] bData = newbyte[1024];
while (-1 != (nLength = is.read(bData))) {
out.write(bData, 0, nLength);
}
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();}}
}

}

客户端调用:

public class FileUploaderTest {
private FileUploader uploader;
private HessianProxyFactory factory = new HessianProxyFactory();
@Test publicvoid testFileUploader() throws FileNotFoundException, MalformedURLException {
uploader = (FileUploader) factory.create(FileUploader.class, "http://localhost:8080/onecoder-shurnim/hessian");
InputStream is = new FileInputStream("/Users/apple/git/onecoder-java/onecoder-shurnim/src/main/resources/logback.xml"); uploader.uplaodFile(is, "logback.xml"); }
 
}

很简单方便。这里曾遇到一个奇怪的问题,如果接口的参数顺序调换,即InputStream在前则会报错:

com.caucho.hessian.io.HessianProtocolException: uplaodFile: expected string at 0x3c (<)

Hessian协议没有深入研究,不知道是不是一个约定或是要求。开发时需要注意。

如果集成spring,只需将servlet交由spring的代理里即可,修改配置即可:

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 
<beans>         
<bean id="defaultHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>        
 <bean id="fileUploader" class="com.coderli.shurnim.file.HessianFileUploader"/>         
<bean name="/hello" class="org.springframework.remoting.caucho.HessianServiceExporter">                 
     <property name="service" ref="fileUploader"/> 
                <property name="serviceInterface" value="com.coderli.shurnim.file.FileUploader"/>        
 </bean> 
</beans>

亲测spring3.2.2+Hessian4.0.7可用。文件内容保存完整。

    

阅读全文 »

Cloudera CDH4卸载

发表于 2013-04-27

记录卸载过程和问题。现有环境Cloudera Manager + (1 + 2 )的CDH环境。

1、先在Manage管理端移除所有服务。
2、删除Manager Server
在Manager节点运行

$ sudo /usr/share/cmf/uninstall-cloudera-manager.sh

如果没有该脚本,则可以手动删除,先停止服务:

sudo service cloudera-scm-server stop
sudo service cloudera-scm-server-db stop

然后删除:

sudo yum remove cloudera-manager-server
sudo yum remove cloudera-manager-server-db

3、删除所有CDH节点上的CDH服务,先停止服务:

sudo service cloudera-scm-agent hard_stop

卸载安装的软件:

sudo yum remove 'cloudera-manager-*' hadoop hue-common 'bigtop-*'

4、删除残余数据:

sudo rm -Rf /usr/share/cmf /var/lib/cloudera* /var/cache/yum/cloudera*

5、kill掉所有Manager和Hadoop进程(选作,如果你正确停止Cloud Manager和所有服务则无须此步)

$ for u in hdfs mapred cloudera-scm hbase hue zookeeper oozie hive impala flume; do sudo kill $(ps -u $u -o pid=); done

6、删除Manager的lock文件
在Manager节点运行:

sudo rm /tmp/.scm_prepare_node.lock

至此,删除完成。
 

阅读全文 »

Mac下 Hbase部署简介(Mac OSX 10.8.3 + HBase-0.94.6)

发表于 2013-04-07

1、安装JDK。之前在部署Hadoop的时候已经安装完成。
2、下载解压HBase。
3、配置HBase数据存储路径,虽然单机模式可以使用本地文件系统,不过OneCoder还是配置HDFS文件系统。
修改hbase-site.xml

<configuration>
    <property>
        <name>hbase.rootdir</name>
        <value>hdfs://localhost:40000/hbase</value>
    </property>
    <property>
        <name>hbase.cluster.distributed</name>
        <value>true</value>
    </property>
</configuration>

这里hdfs路径跟之前hadoop环境中core-site.xml的配置保持一直。
4、修改conf/hbase-site.xml。配置JAVA_HOME
5、启动HBase

shell>bin/start-hbase.sh

6、验证安装

shell>bin/hbase shell
hbase>status

hbase(main):001:0> status

2013-04-07 22:58:24.203 java[3826:1703] Unable to load realm info from SCDynamicStore
1 servers, 0 dead, 2.0000 average load

部署成功。这里还是存在java的警告。同样配置了-Djava.security.krb5.realm=OX.AC.UK -Djava.security.krb5.kdc=kdc0.ox.ac.uk:kdc1.ox.ac.uk 仍然无法消除。暂且如此。

阅读全文 »

《HighPerformance MySQL》概译 事务日志

发表于 2013-04-07

事务日志使得事务更加高效。每次数据改变的时候,存储引擎可以在内存中修改数据拷贝而不用每次都修改磁盘上数据。这速度很快。随后存储引擎会修改记录写入事务日志,该日志是在磁盘上的从而完成持久化。这也是相对高效的过程。因为,追加日志事件产生的是连续的小范围磁盘上的I/O操作,而不是大范围的随机I/O操作。然后,在随后的某时刻一个进程会更新磁盘上的表。因此,更多存储引擎都采用该技术(被称作:write-ahead loggin WAL) 避免将修改两次写入磁盘。

如果在写入日志之后,写入表数据之前发生了崩溃,存储引擎在重启后也可以进行恢复。恢复机制不通的存储引擎是不同的。

阅读全文 »
1 … 23 24 25 … 36
LiHongZhe

LiHongZhe

onecoder's blog.

354 日志
8 分类
RSS
Creative Commons
Links
  • 酷壳
  • 煮酒品茶
  • 小弟子的网络之路
  • 图表秀-在线图表制作
© 2012 - 2023 LiHongZhe
由 Jekyll 强力驱动
主题 - NexT.Muse
本站访客数 人次 本站总访问量 次