sentry存储连接池配置

sentry作为一个数据权限管理系统,本文不做具体介绍,详细介绍内容可以参考官方文档:http://sentry.apache.org/

在实际应用中,大家很可能会遇到一些问题,需要修改连接池的配置参数(不使用默认参数),而官方文档(包括后文提到的DataNucleus)中又缺少具体参数讲解,所以在本文主要介绍sentry底层存储在使用连接池时该如何配置。

下文以DataNucleus的JDO实现+BoneCP连接池展开,其他的连接池(DBCP、C3P0等)可根据代码剖析部分举一反三。

---------------------------------------------线-------------------------------------------

1 代码剖析

1.1 SentryStore

sentry存储入口是org.apache.sentry.provider.db.service.persistent.SentryStore类,启动服务或启动存储时,都会调用SentryStore的构造方法,传入配置来初始化存储:

  public SentryStore(Configuration conf) throws Exception {
    this.conf = conf;
    Properties prop = getDataNucleusProperties(conf);
    boolean checkSchemaVersion = conf.get(
        ServerConfig.SENTRY_VERIFY_SCHEM_VERSION,
        ServerConfig.SENTRY_VERIFY_SCHEM_VERSION_DEFAULT).equalsIgnoreCase(
        "true");
    if (!checkSchemaVersion) {
      prop.setProperty("datanucleus.schema.autoCreateAll", "true");
      prop.setProperty("datanucleus.autoCreateSchema", "true");
      prop.setProperty("datanucleus.fixedDatastore", "false");
    }
    pmf = JDOHelper.getPersistenceManagerFactory(prop);
    tm = new TransactionManager(pmf, conf);
    verifySentryStoreSchema(checkSchemaVersion);
    long notificationTimeout = conf.getInt(ServerConfig.SENTRY_NOTIFICATION_SYNC_TIMEOUT_MS,
            ServerConfig.SENTRY_NOTIFICATION_SYNC_TIMEOUT_DEFAULT);
    counterWait = new CounterWait(notificationTimeout, TimeUnit.MILLISECONDS);
  }

通过JDOHelper获取PersistenceManagerFactory时,根据prop中的“javax.jdo.PersistenceManagerFactoryClass”参数指定具体实现类。而sentry绝大部分prop都是在SentryStore.getDataNucleusProperties(Configuration conf)中设置的(从方法名上也可以看出来最后指定了DataNucleus实现的JDO),深入之后可以看到一系列sentry的默认配置:

"datanucleus.connectionPoolingType" = "BoneCP";
"datanucleus.validateTables" = "false";
datanucleus.validateColumns" = "false";
"datanucleus.validateConstraints" = "false";
"datanucleus.storeManagerType" = "rdbms";
"datanucleus.schema.autoCreateAll" = "true";
"datanucleus.autoCreateSchema" = "false";
"datanucleus.fixedDatastore" = "true";
"datanucleus.autoStartMechanismMode" = "checked";
DATANUCLEUS_ISOLATION_LEVEL = DATANUCLEUS_REPEATABLE_READ;
"datanucleus.cache.level2" = "false";
"datanucleus.cache.level2.type" = "none";
"datanucleus.query.sql.allowAll" = "true";
"datanucleus.identifierFactory" = "datanucleus1";
"datanucleus.rdbms.useLegacyNativeValueStrategy" = "true";
"datanucleus.plugin.pluginRegistryBundleCheck" = "LOG";
"javax.jdo.PersistenceManagerFactoryClass" = "org.datanucleus.api.jdo.JDOPersistenceManagerFactory";
"javax.jdo.option.DetachAllOnCommit" = "true";
"javax.jdo.option.NonTransactionalRead" = "false";
"javax.jdo.option.NonTransactionalWrite" = "false";
"javax.jdo.option.Multithreaded" = "true";

其中就包括"javax.jdo.PersistenceManagerFactoryClass"="org.datanucleus.api.jdo.JDOPersistenceManagerFactory",本文也就是sentry下的Datanucleus下的连接池配置进行展开。外部指定的数据库URL、userName、password也是在getDataNucleusProperties中进行的设置。

同时,我们还可以看到如何将自定义的javax或datanucleus属性传入sentry:

    for (Map.Entry<String, String> entry : conf) {
      String key = entry.getKey();
      if (key.startsWith(ServerConfig.SENTRY_JAVAX_JDO_PROPERTY_PREFIX) ||
          key.startsWith(ServerConfig.SENTRY_DATANUCLEUS_PROPERTY_PREFIX)) {
        key = StringUtils.removeStart(key, ServerConfig.SENTRY_DB_PROPERTY_PREFIX);
        prop.setProperty(key, entry.getValue());
      }
    }

只要带有“sentry.javax.jdo”或“sentry.datanucleus”前缀,就会截掉“sentry.”前缀,将剩余的部分设置到prop中。

1.2 ConnectionFactoryImpl

继续跟进代码,可以看到DataNucleus在org.datanucleus.store.rdbms.ConnectionFactoryImpl的initialiseDataSources()方法中初始化了数据源。

其根据上述参数中的"datanucleus.connectionPoolingType"来决定连接池类型:

requiredPoolingType = storeMgr.getStringProperty("datanucleus.connectionPoolingType");

我们以上述sentry默认的BoneCP为例继续进行讲解。

1.3 BoneCPConnectionPoolFactory

知道连接池的类型为BoneCP后,通过org.datanucleus.store.rdbms.connectionpool.BoneCPConnectionPoolFactory的createConnectionPool方法创建连接池。在这个工厂类里面,一切参数都一幕了然了:

        // Create the actual pool of connections
        com.jolbox.bonecp.BoneCPDataSource ds = new com.jolbox.bonecp.BoneCPDataSource(config);

        // Apply any BoneCP properties
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_STATEMENTS))
        {
            int size = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_STATEMENTS);
            if (size >= 0)
            {
                ds.setStatementsCacheSize(size);
            }
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_POOL_SIZE))
        {
            int size = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_POOL_SIZE);
            if (size >= 0)
            {
                ds.setMaxConnectionsPerPartition(size);
            }
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MIN_POOL_SIZE))
        {
            int size = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MIN_POOL_SIZE);
            if (size >= 0)
            {
                ds.setMinConnectionsPerPartition(size);
            }
        }
        if (storeMgr.hasProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_IDLE))
        {
            int value = storeMgr.getIntProperty(RDBMSPropertyNames.PROPERTY_CONNECTION_POOL_MAX_IDLE);
            if (value > 0)
            {
                ds.setIdleMaxAgeInMinutes(value);
            }
        }

可以看到,有4个自定义参数可以设置:

Constant

Content

Description

PROPERTY_CONNECTION_POOL_MAX_STATEMENTS

datanucleus.connectionPool.maxStatements

最大缓存语句数

PROPERTY_CONNECTION_POOL_MAX_POOL_SIZE

datanucleus.connectionPool.maxPoolSize

每个partition的最大连接数

PROPERTY_CONNECTION_POOL_MIN_POOL_SIZE

datanucleus.connectionPool.minPoolSize

每个partition的最小连接数

PROPERTY_CONNECTION_POOL_MAX_IDLE

datanucleus.connectionPool.maxIdle

连接的最大空闲时间

(DataNucleus的官方文档中,只提到了前三个BoneCP配置参数:http://www.datanucleus.org/products/accessplatform_4_1/jdo/datastore_connection.html

2 参数配置

考虑sentry截掉前缀的特性,正确配置BoneCP连接池的参数如下:

DataNucleus Parameter

Sentry Parameter

datanucleus.connectionPool.maxStatements

sentry.datanucleus.connectionPool.maxStatements

datanucleus.connectionPool.maxPoolSize

sentry.datanucleus.connectionPool.maxPoolSize

datanucleus.connectionPool.minPoolSize

sentry.datanucleus.connectionPool.minPoolSize

datanucleus.connectionPool.maxIdle

sentry.datanucleus.connectionPool.maxIdle

(其余类型连接池的参数可以此类推。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值