使用Spark从Oracle db读取数据时如何实现更多并行性

时间:2019-04-17 07:49:04

标签: apache-spark ojdbc azure-databricks

我在蔚蓝的数据块上运行火花。我的要求是我需要从oracle db中提取数据并将其输出推到文件中。

Spark verison - 2.4
Databricks cluster size - 8 nodes,8 cores for each node.

因此,为了获得更多的并行性,我在oracle查询的分区列上使用了哈希算法。

example - mod(ora_hash(id), 64) as partition_key

问题是,尽管我在Data-bricks集群中有64个核心,但是只有8个核心正在运行以从oracle中提取数据。

请找到所附的屏幕截图以供参考。

executors tab executor tab with task level

以下是代码-

     spark
      .read
      .format("jdbc")
      .option("url", jdbc_url)
      .option("dbtable",crmquery)
      .option("lowerBound", 0)
      .option("upperBound", 64)
      .option("partitionColumn", "partition_key")
      .option("numPartitions", 64)
      .option("Driver",driverClass)
      .option("user", user)
      .option("password", pswd)
      .option("fetchsize",1000)
      .load()
      .write
      .option("header", "true")
      .option("escape","")
      .option("inferSchema", "false")
      .csv(path)

有人可以帮助我,如何在阅读时增加与oracle DB的更多连接?我可以使用56个核心。

谢谢。

1 个答案:

答案 0 :(得分:0)

在使用Spark进行读取之前,您不必对数据进行哈希处理,我会说这会引起问题。下限和上限使Spark重新运行您的查询,添加WHERE子句以将数据读入分区,如下所示:

def _build_net(self):

    with tf.device('/gpu:0'):
        # Convolutional Layer #3 and Pooling Layer #3
        conv3 = tf.layers.conv2d(inputs=dropout2, filters=64, kernel_size=[3, 3], padding="SAME", activation=tf.nn.relu,  kernel_initializer=tf.contrib.layers.xavier_initializer())
        print('conv3:' + str(conv3))
        pool3 = tf.layers.max_pooling2d(inputs=conv3, pool_size=[2, 2], padding="SAME", strides=2)
        print('pool3:' + str(pool3))
        dropout3 = tf.layers.dropout(inputs=pool3, rate=0.6, training=self.training)
        print('dropout3:' + str(dropout3))

    with tf.device('/gpu:1'):
        # Dense Layer with Relu
        flat = tf.reshape(dropout3, [-1, 16*16*64]) # flat should be same with size of last dropout
        print('flat:' + str(flat))
        dense = tf.layers.dense(inputs=flat, units=1024, activation=tf.nn.relu)
        print('dense:' + str(dense))
        dropout_dense = tf.layers.dropout(inputs=dense, rate=0.6, training=self.training)
        print('dropout_dense:' + str(dropout_dense))

        self.logits = tf.layers.dense(inputs=dropout_dense, units=n_classes)
        print('logits:' + str(self.logits))

    # define cost/loss & optimizer
    self.cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=self.logits, labels=self.Y))
    print('cost:' + str(self.cost))
    self.optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(self.cost)
    print('optimizer:' + str(self.optimizer))

    correct_prediction = tf.equal(tf.argmax(self.logits, 1), tf.argmax(self.Y, 1))
    print('correct_prediction:' + str(correct_prediction))
    self.accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    print('accuracy:' + str(self.accuracy))

def predict(self, x_test, training=False):
    return self.sess.run(self.logits, feed_dict={self.X: x_test, self.training: training})

def get_accuracy(self, x_test, y_test, training=False):
    return self.sess.run(self.accuracy, feed_dict={self.X: x_test, self.Y: y_test, self.training: training})

def train(self, x_data, y_data, training=True):
    return self.sess.run([self.cost, self.optimizer], feed_dict={self.X: x_data, self.Y: y_data, self.training: training})

...

由于您之前对数据进行了哈希处理,所以您没有任何partition_key> = 64的数据

仅指定partitionColumn,lowerBound,upperBound和numPartitions应该可以实现所需的功能。 另外,我认为您最好依靠jdbc method而不是使用所有这些选项的格式。

希望这会有所帮助。