zoukankan      html  css  js  c++  java
  • 将eucalyptus数据库更改为Mysql

    简介
    项目中用到了eucalyptus的东西,在eucalyptus中,数据库采用的是hsqldb,一种轻量级的小型数据库,eucalyptu将其紧密地集成在系统当中。若是从外部访问eucalyptus数据信息,感觉颇为不便。故考虑将eucalyptu的数据库从hsqldb迁移到mysql中。这样的话,从外部可以很方便地访问需要的信息。下面介绍更改的过程,如有需要可以参考。

    相关文件介绍
     eucalyptus中,访问数据库的部分采用了hibernate的封装,由hibernate屏蔽了底层数据库的差异性,因而在由hsqldb迁移到mysql中,无需对系统作出大的改动即可迁移成功。
    在eucalyptu中,与数据库配置以及初始化相关的文件有:

    1 clc/modules/database/conf/scripts/before_database.groovy
    2 clc/modules/database/conf/scripts/after_database.groovy
    3 clc/modules/database/conf/scripts/pools.groovy
    4 clc/modules/database/conf/scripts/caches.groovy

    上述的四个groovy文件是关于eucalyptu使用的数据库的初始化脚本,以及关于hibernate的配置,线程池的一些配置优化。
    clc/modules/database/src/main/java/com/eucalyptus/bootstrap/LocalDatabaseBootstrapper.java
    该文件是Database的的初始化过程,在其中通过调用上述的四个脚本文件完成eucalyptus的数据库的初始化操作,并且启动数据库服务。其服务的基本启动过程与其它eucalyptus服务启动类似,必须实现一些统一的Bootstrapper接口。
    clc/modules/database/src/main/java/com/eucalyptus/bootstrap/DatabaseConfig.java
    该文件是原始hsqldb数据库服务的基本配置,包括端口、数据库文件等。如果更换成mysql后,该文件没有存在的必要,可以删掉。
    clc/modules/hsqldb/src/main/resources/com.eucalyptus.CloudServiceProvider
    eucalyptus是以组件的形式,也就是component的方式连接建立起来的,上述文件就是关于db component的配置,其中有component的一些服务port和url等信息。比如此处要修改的数据库服务信息等。
    clc/modules/core/src/main/java/com/eucalyptus/bootstrap/RemoteDatabaseBootstrapper.java
    该文件不知道要作何用,但是其中有关于数据库密码的一些信息,直接设置到了eucalyptus运行环境的property中。这个property在pools.groovy中有用到,用于设置一些关于hibernate的信息,因而也需要对该文件进行一些简单的处理。

    数据库初始化过程
    上边是一些要用到可能需要修改的文件,在eucalyptus中,数据库的初始化过程简单介绍如下,基于自己理解,可能会有错误。clc/modules/msgs/src/main/java/com/eucalyptus/bootstrap/Bootstrap.java,这是clc java部分引导启动之后的第一个实例。执行component的初始化过程,初始化过程包括eucalyptus的服务的发现、加载、启动,各个component的初始化,配置文件的加载,其中包括LocalDatabaseBootstrapper服务,也就是在此处,对clc/modules/hsqldb/src/main/resources/com.eucalyptus.CloudServiceProvider的资源文件进行加载处理,并对component db做了初始化处理,其中包括db的url初始化,这是一个比较关键的信息。也只有在该url被完成之后,后续的hibernate对数据库进行初始化才可以进行。
    在db component初始化完成后,剩余的将会交给hibernate进行数据库的初始化操作了。对数据库的初始化操作,主要集中在clc/modules/database/src/main/java/com/eucalyptus/bootstrap/LocalDatabaseBootstrapper.java,在bootstrapper中,对数据库的操作主要集中在load中的createDatabase,也就是在其中,执行上述的before_database.groovy、after_database.groovy,在脚本中完成对数据库的操作。

    用到的基本原理
    基于上述的一些服务启动过程解释,也就是只需要修改上述的一些文件就可以了。这其中需要了解的一些原理包括hibernate的annotation,groovy的lamba表达式,向groovy中变量参数的传递,数据库的连接池配置,hibernate连接数据库的property配置,mysql创建数据库的规则。此处不再赘述。可以通过详细的更改迁移过程了解。

    具体改动过程
    下面介绍具体实施中的改动过程:
    具体的更改详细过程如下:
    1、对com.eucalyptus.CloudServiceProvider进行更改配置

    name=db 表示对应的component
    euca.model.dns=db-model.xml 貌似是mule使用的xml配置文件
    euca.model.dns.services=db-services.xml 貌似是mule使用的xml配置文件
    euca.url.local=//127.0.0.1:3306/eucalyptus mysql数据库的url配置
    euca.url.pattern=//%s:%d/eucalyptus url的匹配模式
    euca.url.port=3306 mysql的默认端口
    此处更改的文件在clc/modules/hsqldb/src/main/resources/com.eucalyptus.CloudServiceProvider

    2、更改LocalDatabaseBootstrapper的实现
    修改借口的实现包括start、run。在该类的实现中,主要是删除一些不必要的功能。
    修改的文件在clc/modules/database/src/main/java/com/eucalyptus/bootstrap/LocalDatabaseBootstrapper.java

    3、修改初始化groovy脚本
    有一部分是直接借用于原来的脚本,并对此作出了部分更改。

    下面是before_database.groovy脚本,先在mysql中创建好数据库

    import com.eucalyptus.system.SubDirectory;
    import com.eucalyptus.entities.PersistenceContexts;
    import com.eucalyptus.bootstrap.Component;
    import com.eucalyptus.util.*;

    //init the db setting
    //set the mysql char set to utf8
    config ="default-character-set=utf8\ndefault-collation=utf8"
    //此处是关于mysql的数据库初始化的一些基本配置,此处将其设置为utf8
    //此处经过测试汉语不会出现乱码
    //create the db file name create the new db file
    //through the anonation from the db
    Runtime runtime = null;
    try
    {
    runtime = Runtime. getRuntime();
    }
    catch(Exception e)
    {
    e.printStackTrace();
    System.exit(1)
    }
    //获取运行时用于更改创建的文件夹权限,以便mysql有权限进行读写操作
    //此处采用的是执行linux命令的方式,java内部的api目前无法实现该功能
    //此处是hibernate通过java的annotation获取到需要建立的数据库信息以及表的信息
    //具体可以参考clc/modules/msgs/arc/main/java/com/eucalyptus/entities中的具体实现文件
    PersistenceContexts.list( ).each{ context_name ->
    db = new File("${SubDirectory.DB.toString()}/${context_name}");
    opt = new File("${SubDirectory.DB.toString()}/${context_name}/db.opt");
    //the db not exist create the db
    if( !db.exists() ) {
    db.mkdir();
    //the mysql db.opt conf not exist
    if( !opt.exists() ) {
    opt.write(config);
    }
    //在mysql数据库中,创建一个空的数据库的一个简便方法就是在mysql的data文件夹下
    //创建对应的数据库名字的文件夹即可,在该文件夹下的db.opt主要是用于配置该数据库的
    //一些编码规则,规则比较简单,此处将编码配置为utf8
    command = "chmod 777 -R " + "${SubDirectory.DB.toString()}/${context_name}";
    try
    {
    runtime. exec(command);
    //change the eucalyptus db file permission to mysql
    }
    catch(Exception e)
    {
    e.printStackTrace();
    System.exit(1)
    }
    //在创建完成后,这些文件权限是755,属于eucalyptus用户所有
    //mysql根本没有权限进行写入,会造成后期的table创建错误
    //因此需要将权限开放给mysql用户
    }
    }




    after_database.groovy脚本,完成对数据库中table表的创建

    import com.eucalyptus.entities.PersistenceContexts;
    import org.hibernate.ejb.*
    import com.eucalyptus.util.*
    import edu.ucsb.eucalyptus.cloud.ws.*;
    //conf hibernate
    //这是hibernate的一些property配置
    hiber_config = [
    'hibernate.archive.autodetection': 'jar, class, hbm',
    'hibernate.show_sql': 'false',
    'hibernate.format_sql': 'false',
    'hibernate.connection.autocommit': 'true',
    'hibernate.hbm2ddl.auto': 'update',
    'hibernate.generate_statistics': 'true',
    ]

    contexts = PersistenceContexts.list( );//list the db
    //上述的contexts是数据库名列表,在before_database.groovy中已经使用过,
    //列出的数据库已经创建完成了
    //下面就是创建数据库中表的过程

    contexts.each { String ctxName ->
    String it = ctxName.replaceAll("eucalyptus_","")
    pool_config = new pools(new Binding([context_name:it])).run()
    //设置对应的数据库连接池
    //正常情况下,每一个数据库对应一个独立的url
    //比如eucalyptus_auth和eucalyptus_general分别对应的url是:
    ////127.0.0.1:3306/eucalyptus_auth”和“//127.0.0.1:3306/eucalyptus_general”
    //通过传入pool.groovy中的 context_name进行对应连接池中url的设置

    cache_config = new caches(new Binding([context_name:it])).run()
    //这是hibernate的缓存设置,没有特别特殊的地方

    config = new Ejb3Configuration();
    LogUtil.logHeader( "Hibernate for ${ctxName}" ).log(hiber_config.inspect())
    hiber_config.each { k, v -> config.setProperty(k, v) }
    LogUtil.logHeader( "Pool for ${ctxName}").log( pool_config.inspect() )
    pool_config.each { k, v -> config.setProperty(k, v) }
    LogUtil.logHeader( "Cache for ${ctxName}").log( cache_config )
    cache_config.each { k, v -> config.setProperty(k, v) }
    entity_list = PersistenceContexts.listEntities( ctxName )
    LogUtil.logHeader("Entities for ${ctxName}")
    entity_list.each{ ent ->
    LogUtil.log( ent.toString() )
    config.addAnnotatedClass( ent )
    }
    //获取数据库所包含的表,此处通过annotation标记,只需知道对应table的类就可以
    try {
    PersistenceContexts.registerPersistenceContext("${ctxName}", config)
    //注册table,并进行table的创建
    } catch( Throwable t ) {
    t.printStackTrace();
    System.exit(1)
    }
    }



    关于pools.groovy,主要就是上边提到的连接代理的问题,更改后的代码如下:

    import com.eucalyptus.bootstrap.Component;
    import org.logicalcobwebs.proxool.ProxoolFacade;
    import com.eucalyptus.util.LogUtil;
    //set hibernate username and passwd

    db_pass = System.getProperty("euca.db.password")!=null && System.getProperty("euca.db.password").length()>1 ? System.getProperty("euca.db.password") : "123456";
    //此处连接用的用户名暂设为root,密码为“123456”
    ClassLoader.getSystemClassLoader().loadClass('org.logicalcobwebs.proxool.ProxoolDriver');
    poolProps = [
    'proxool.simultaneous-build-throttle': '16',
    'proxool.minimum-connection-count': '16',
    'proxool.maximum-connection-count': '128',
    'proxool.house-keeping-test-sql': 'SELECT * FROM COUNTERS;',
    'user': 'root',
    'password': db_pass,
    ]

    //set hibernate pool conf
    p = new Properties();
    p.putAll(poolProps)
    String dbDriver = 'com.mysql.jdbc.Driver';

    //set the proxool url
    //just like mysql url jdbc:mysql://localhost:3306/db_name

    String url = "proxool.eucalyptus_${context_name}:${dbDriver}:jdbc:mysql:${Component.db.uri.toASCIIString( )}_${context_name}";

    //此处用到了db component的url信息
    //context_name pass from after_database
    LogUtil.logHeader( "Proxool config for ${context_name}" ).log( url ).log( poolProps )
    ProxoolFacade.registerConnectionPool(url, p);

    [
    'hibernate.bytecode.use_reflection_optimizer': 'true',
    'hibernate.cglib.use_reflection_optimizer': 'true',
    'hibernate.dialect': 'org.hibernate.dialect.MySQLDialect',
    'hibernate.connection.provider_class': 'org.hibernate.connection.ProxoolConnectionProvider',
    'hibernate.proxool.pool_alias': "eucalyptus_${context_name}",
    'hibernate.proxool.existing_pool': 'true'
    ]

    4、RemoteDatabaseBootstrapper 的修改
    在 RemoteDatabaseBootstrapper中,在服务加载的过程中,设置了eucalyptus的"euca.db.password"property,此处设置的password在pool中需要用到,并且为了扩展需要,密码也需要在mysql中进行设置,故没有在此处设置属性,只是在clc/modules/core/src/main/java/com/eucalyptus/bootstrap/RemoteDatabaseBootstrapper.java的81行,去掉了该设置语句。

    5、添加必需的mysql jdbc包
    由于连接mysql需要的对应的jdbc包,因而在clc的lib下添加了mysql-connector-java-5.1.18-bin.jar包,此包可以在mysql的官网下载.
    6、修改eucalyptus中的euca_conf中的一些关于用户id的一些获取方法。也就是通过读数据库而已,比较简单。


    更改后需要进行的系统配置:
    1、首先配置mysql的 datadir和 max_connections
    mysql的数据目录配置,在/etc/my.cnf文件中

        [mysqld]
    datadir=/$EUCALYPTUS/eucalyptus/db
    socket=/var/lib/mysql/mysql.sock
    user=mysql
    max_connections = 200

    在eucalyptus首次安装后,进行自动化配置时,需要将 datadir的目录设置到eucalyptus的db目录下;同时 max_connections也必须设置,默认为101,但是在eucalyptus的连接池中配置为126,如果不进行修改,会造成数据库无法连接读取,出现异常。
    2、配置mysql后,重新启动mysql数据库
    /etc/init.d/mysqld restart
    以将mysql的数据文件定位到设置好的目录下
    3、设置mysql的用户名和密码
    目前暂时用的是root:123456,密码可以通过 mysqladmin -u root password "123456",将其设置为 123456,当然密码也可以设置为其它,但是应当与/$EUCALYPTUS/etc/eucalyptus/cloud.d/scripts/pools.groovy中的密码相匹配。
    但是这仅限于初次mysql的密码设置。
    4、mysql重新启动后,修改eucalyptus的db目录权限
    chmod 777 /$EUCALYPTUS/eucalyptus/db

     由于mysql服务重新启动后,会将db的权限更改为755,并且db文件夹属于mysql。如果不进行权限设置,在eucalyptus初次启动时没有权限向该文件夹下写数据。
    至此eucalyptus的初始化配置已经基本完成,并且mysql或是eucalyptus的重启不会再有文件权限的困扰。当然,这些还需要更多环境的测试。
    如果删除了db下的数据库文件,并且mysql重新启动过,则需要进行上述步骤4的操作。
    如果eucalyptus进行重装,则基本配置过程同上述类似。


    经过上边的过程,已经基本算是完结了。由于linux用户权限的问题,在使用的过程中上述的更改可能会造成使用不便。如果需要的话,可以考虑将db数据库目录与eucalyptus单独分开来,这样就不会有用户权限的困扰了。

    上述的过程已经经过测试,并且可用。有需要的朋友可以参考下。

  • 相关阅读:
    RedisUtil
    CSS基础知识点笔记
    fdgfgfgfgf
    PerfMon Metrics Collector插件的Disks I/O使用总结
    Jmeter使用笔记之html报告扩展(一)
    Jmeter使用笔记之意料之外的
    Jmeter使用笔记之函数
    Jmeter使用笔记之组件的作用域
    css 初始化文件 全面
    vue-grid-layout 使用以及各项参数作用
  • 原文地址:https://www.cnblogs.com/hanxiangduo/p/Change_eucalyptus_db_from_hsqldb2mysql.html
Copyright © 2011-2022 走看看