How to enable GC logging for Apache HiveServer2/MetaStore server/WebHCat server, while preventing log file overwrites and capping disk space usage - hadoop

We recently decided to enable GC logging for three Apache Hive-related servers: HiveServer2, Hive MetaStore server, and WebHCat server. This is on a number of clusters (exact version varies) as a aid to looking into Hive-related memory and garbage collection problems. While doing this, we want to avoid two problems we know might happen:
overwriting of the log file when a server restarts for any reason
the logs using too much disk space, leading to disks getting filled
When Java GC logging starts for a process it seems to replace the content of any file that has the same name. This means that unless you are careful, you will lose the GC logging, perhaps when you are more likely to need it.
If you keep the cluster running long enough, log files will fill up disk unless managed. Even if GC logging is not currently voluminous we want to manage the risk of an unusual situation arising that causes the logging rate to suddenly spike up.

How you do this will be a little different for HiveServer2 and Hive MetaStore server vs WebHCat server. I'll answer both. In both cases you'll need to set some JVM parameters when starting the servers.
For HiveServer2 and Hive MetaStore server the Java parameters will be set in hive-env.sh. It appears these need to be set in HADOOP_OPTS, but we'll need to be careful to limit the scope of the change to the two server (and not other cases in which hive-env.sh is run).
For WebHCat server, you will also be setting HADOOP_OPTS but there doesn't seem to be a "env.sh" file in the distribution invoked when starting the server, so you'll need to set it in the environment prior to running WebHCat server. However, in Ambari, there is a webhcat-env config group.
Now lets discuss the JVM parameters to include in these cases.
To enable GC logging to a file, you will need to add -verbose:gc -Xloggc:<log-file-location>.
You need to give the log file name special consideration to prevent overwrites whenever the servers are restarted. It seems like you need to have a unique name for every invocation so appending a timestamp seems like the best option. You can include something like `date +'%Y%m%d%H%M'` to add a timestamp. In this example, it is in the form of YYYYMMDDHHMM. In some versions of Java you can put "%t" in your log file location and it will be replaced by the server start up timestamp formatted as YYYY-MM-DD_HH-MM-SS.
Now onto managing use of disk space. I'll be happy if there is a simpler way than what I have.
First, take advantage of Java's built-in GC log file rotation. -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M is an example of enabling this rotation, having up to 10 GC log files from the JVM, each of which is no more than approx 10MB in size. 10 x 10MB is 100MB max usage.
With the GC log file rotation in place with up to 10 files, '.0', '.1', ... '.9' will be added to the file name you gave in Xloggc. .0 will be first and after it reaches .9 it will replace .0 and continue on in a round robin manner. In some versions of Java '.current' will be additionally put on the end of the name of the log file currently being written to.
Due to the unique file naming we apparently have to have to avoid overwrites, you can have 100MB per server process invocation, so this is not a total solution to managing disk space used by the Hive server logs. You will end up with a set of up to 10 GC log files on each server invocation -- this can add up over time. The best solution (under *nix) to that would seem to be to use the logrotate utility (or some other utility) to periodically clean up the GC logs that have not been modified in the last N days.
Be sure to do the math and make sure you will have enough disk space. Note that on some master servers you might be running all three kinds of servers.
People frequently want more details and context in their GC logs than the default, so consider adding in -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps.
Putting this together for HiveServer2 and Hive MetaStore server, you might add something this to hive-env:
# note that $SERVICE is a string saying what it is that is being started
if [[ "$SERVICE" == "hiveserver2" || "$SERVICE" == "metastore" ]]; then
TIMESTAMP=`date +'%Y%m%d%H%M'`
# GC log location/name prior to .n addition by log rotation
HIVE_SERVERS_GC_LOG_NAME="{{hive_log_dir}}/hive-$SERVICE-gc.log-$TIMESTAMP"
HIVE_SERVERS_GC_LOG_ENABLE_OPTS="-verbose:gc -Xloggc:$HIVE_SERVERS_GC_LOG_NAME"
HIVE_SERVERS_GC_LOG_ROTATION_OPTS="-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M"
HIVE_SERVERS_GC_LOG_FORMAT_OPTS="-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps"
HIVE_SERVERS_GC_LOG_OPTS="$HIVE_SERVERS_GC_LOG_ENABLE_OPTS $HIVE_SERVERS_GC_LOG_ROTATION_OPTS $HIVE_SERVERS_GC_LOG_FORMAT_OPTS"
export HADOOP_OPTS="$HADOOP_OPTS $HIVE_SERVERS_GC_LOG_OPTS"
fi
This takes advantage of $SERVICE, set by Hive, to determine what kind of process is being started and to only set the environment variables when it is HiveServer2 or MetaStore server.
In the above, you can change {{hive_log_dir}} to wherever you want the GC logs to go (you probably want it to go the the same place as server's main logs). You can change the log file naming too.
If you are managing your Hadoop cluster with Apache Ambari, then these changes would be in Hive service > Configs > Advanced > Advanced hive-env > hive-env template. With Ambari, {{hive_log_dir}} will be automatically replaced with the Hive Log Dir defined a few rows above the field.
Now for WebHCat server being manually invoked you can set the following in the environment beforehand:
TIMESTAMP=`date +'%Y%m%d%H%M'`
# GC log location/name prior to .n addition by log rotation
WEBHCAT_GC_LOG_NAME="{{templeton_log_dir}}/webhcat-server-gc.log-$TIMESTAMP"
WEBHCAT_GC_LOG_ENABLE_OPTS="-verbose:gc -Xloggc:$WEBHCAT_GC_LOG_NAME"
WEBHCAT_GC_LOG_ROTATION_OPTS="-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M"
WEBHCAT_GC_LOG_FORMAT_OPTS="-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps"
WEBHCAT_GC_LOG_OPTS="$WEBHCAT_GC_LOG_ENABLE_OPTS $WEBHCAT_GC_LOG_ROTATION_OPTS $WEBHCAT_GC_LOG_FORMAT_OPTS"
HADOOP_OPTS="$HADOOP_OPTS $WEBHCAT_GC_LOG_OPTS"
If you are managing your Hadoop cluster with Apache Ambari, then you would do similar to changes in Hive service > Configs > Advanced > Advanced webhcat-env > webhcat-env template. With Ambari, {{templeton_log_dir}} will be automatically replaced with the WebHCat Log Dir defined a couple rows above the field. The one change to the above Bash lines I did was to replace -server- in the log file name with -$$- since I don't know if WebHCat server is the only thing that webhcat-env is run for (this both prevents implying that is the server for sure and prevents conflicts by adding the PID).
In all these cases GC logging will start happening upon server restart. Consider a rolling restart for HiveServer2 and Hive MetaStore.

Related

How to enable GC logging for Hadoop MapReduce2 History Server, while preventing log file overwrites and capping disk space usage

We recently decided to enable GC logging for Hadoop MapReduce2 History Server on a number of clusters (exact version varies) as a aid to looking into history-server-related memory and garbage collection problems. While doing this, we want to avoid two problems we know might happen:
overwriting of the log file when the MR2 History server restarts for any reason
the logs using too much disk space, leading to disks getting filled
When Java GC logging starts for a process it seems to replace the content of any file that has the same name. This means that unless you are careful, you will lose the GC logging, perhaps when you are more likely to need it.
If you keep the cluster running long enough, log files will fill up disk unless managed. Even if GC logging is not currently voluminous we want to manage the risk of an unusual situation arising that causes the logging rate to suddenly spike up.
You will need to set some JVM parameters when starting the MapReduce2 History Server, meaning you need to make some changes to mapred-env.sh. You could set the parameters in HADOOP_OPTS, but that would have a broader impact than just the History server, so instead you will probably want to set them in HADOOP_JOB_HISTORYSERVER_OPTS.
Now lets discuss the JVM parameters to include in those.
To enable GC logging to a file, you will need to add -verbose:gc -Xloggc:<log-file-location>.
You need to give the log file name special consideration to prevent overwrites whenever the server is restarted. It seems like you need to have a unique name for every invocation so appending a timestamp seems like the best option. You can include something like `date +'%Y%m%d%H%M'` to add a timestamp. In this example, it is in the form of YYYYMMDDHHMM. In some versions of Java you can put "%t" in your log file location and it will be replaced by the server start up timestamp formatted as YYYY-MM-DD_HH-MM-SS.
Now onto managing use of disk space. I'll be happy if there is a simpler way than what I have.
First, take advantage of Java's built-in GC log file rotation. -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M is an example of enabling this rotation, having up to 10 GC log files from the JVM, each of which is no more than approx 10MB in size. 10 x 10MB is 100MB max usage.
With the GC log file rotation in place with up to 10 files, '.0', '.1', ... '.9' will be added to the file name you gave in Xloggc. .0 will be first and after it reaches .9 it will replace .0 and continue on in a round robin manner. In some versions of Java '.current' will be additionally put on the end of the name of the log file currently being written to.
Due to the unique file naming we apparently have to have to avoid overwrites, you can have 100MB per History server invocation, so this is not a total solution to managing disk space used by the server's GC logs. You will end up with a set of up to 10 GC log files on each server invocation -- this can add up over time. The best solution (under *nix) to that would seem to be to use the logrotate utility (or some other utility) to periodically clean up the GC logs that have not been modified in the last N days.
Be sure to do the math and make sure you will have enough disk space.
People frequently want more details and context in their GC logs than the default, so consider adding in -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps.
Putting this together, you might add something this to mapred-env:
## enable GC logging for MR2 History Server:
TIMESTAMP=`date +'%Y%m%d%H%M'`
# GC log location/name prior to .n addition by log rotation
JOB_HISTORYSERVER_GC_LOG_NAME="{{mapred_log_dir_prefix}}/$USER/mapred-jobhistory-gc.log-$TIMESTAMP"
JOB_HISTORYSERVER_GC_LOG_ENABLE_OPTS="-verbose:gc -Xloggc:$JOB_HISTORYSERVER_GC_LOG_NAME"
JOB_HISTORYSERVER_GC_LOG_ROTATION_OPTS="-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M"
JOB_HISTORYSERVER_GC_LOG_FORMAT_OPTS="-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps"
JOB_HISTORYSERVER_GC_LOG_OPTS="$JOB_HISTORYSERVER_GC_LOG_ENABLE_OPTS $JOB_HISTORYSERVER_GC_LOG_ROTATION_OPTS $JOB_HISTORYSERVER_GC_LOG_FORMAT_OPTS"
export HADOOP_JOB_HISTORYSERVER_OPTS="$HADOOP_JOB_HISTORYSERVER_OPTS $JOB_HISTORYSERVER_GC_LOG_OPTS"
You may find that you already have a reference to HADOOP_JOB_HISTORYSERVER_OPTS so you should replace or add onto that.
In the above, you can change {{mapred_log_dir_prefix}}/$USER to wherever you want the GC logs to go (you probably want it to go the the same place as MapReduce history server logs). You can change the log file naming too.
If you are managing your Hadoop cluster with Apache Ambari, then these changes would be in MapReduce2 service > Configs > Advanced > Advanced mapred-env > mapred-env template. With Ambari, {{mapred_log_dir_prefix}} will be automatically replaced with the Mapreduce Log Dir Prefix defined a few rows above the field.
GC logging will start happening upon server restart the server, so you may need to have a short outage to enable this.

How to enable GC logging for Hadoop YARN ResourceManager and ApplicationTimeline, while preventing log file overwrites and capping disk space usage

We recently decided to enable GC logging for Hadoop YARN ResourceManager and ApplicationTimeline servers on a number of clusters (exact version varies) as a aid to looking into YARN-related memory and garbage collection problems. While doing this, we want to avoid two problems we know might happen:
overwriting of the log file when a YARN RM or AT server restarts for any reason
the logs using too much disk space, leading to disks getting filled
When Java GC logging starts for a process it seems to replace the content of any file that has the same name. This means that unless you are careful, you will lose the GC logging, perhaps when you are more likely to need it.
If you keep the cluster running long enough, log files will fill up disk unless managed. Even if GC logging is not currently voluminous we want to manage the risk of an unusual situation arising that causes the logging rate to spike up.
You will need to set some JVM parameters when starting the YARN servers, meaning you need to make some changes to yarn-env.sh. You could set the parameters in YARN_OPTS, but that would have a broader impact than just the ResourceManager and ApplicationTimeline servers, so instead you will probably want to set then in both YARN_RESOURCEMANAGER_OPTS and YARN_TIMELINESERVER_OPTS.
Now lets discuss the JVM parameters to include in those.
To enable GC logging to a file, you will need to add -verbose:gc -Xloggc:<log-file-location>.
You need to give the log file name special consideration to prevent overwrites whenever the server is restarted. It seems like you need to have a unique name for every invocation so appending a timestamp seems like the best option. You can include something like `date +'%Y%m%d%H%M'` to add a timestamp. In this example, it is in the form of YYYYMMDDHHMM. In some versions of Java you can put "%t" in your log file location and it will be replaced by the server start up timestamp formatted as YYYY-MM-DD_HH-MM-SS.
Now onto managing use of disk space. I'll be happy if there is a simpler way than what I have.
First, take advantage of Java's built-in GC log file rotation. -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M is an example of enabling this rotation, having up to 10 GC log files from the JVM, each of which is no more than approx 10MB in size. 10 x 10MB is 100MB max usage.
With the GC log file rotation in place with up to 10 files, '.0', '.1', ... '.9' will be added to the file name you gave in Xloggc. .0 will be first and after it reaches .9 it will replace .0 and continue on in a round robin manner. In some versions of Java '.current' will be additionally put on the end of the name of the log file currently being written to.
Due to the unique file naming we apparently have to have to avoid overwrites, you can have 100MB per RM or AT server process invocation, so this is not a total solution to managing disk space used by the YARN GC logs. You will end up with a set of up to 10 GC log files on each server invocation -- this can add up over time. The best solution (under *nix) to that would seem to be to use the logrotate utility (or some other utility) to periodically clean up the GC logs that have not been modified in the last N days.
Be sure to do the math and make sure you will have enough disk space. Note that you might be running a ResourceManager and a ApplicationTimeline on the same master server.
People frequently want more details and context in their GC logs than the default, so consider adding in -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps.
Putting this together, you might add something this to yarn-env:
# this function takes the name of a YARN component as input and returns the JVM options
# to enable GC logging for the component. The option string is set in the variable named
# as the second arg
function yarn_gc_log_opts_for_component()
{
# get function args
local component_name=$1
local __resultvar=$2
# calculate GC log name
local timestamp_str=`date +'%Y%m%d%H%M'`
local gc_log_name="{{yarn_log_dir_prefix}}/$USER/yarn-${component_name}-gc.log-${timestamp_str}"
# calculate GC logging options for enablement, rotation, and format
local gc_log_enable_opts="-verbose:gc -Xloggc:$gc_log_name"
local gc_log_rotation_opts="-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M"
local gc_log_format_opts="-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps"
# combing these options and return the result
local gc_log_opts="$gc_log_enable_opts $gc_log_rotation_opts $gc_log_format_opts"
eval $__resultvar="'$gc_log_opts'"
}
# get options for GC logging for YARN ResourceManager servers and put them into use
yarn_gc_log_opts_for_component "resourcemanager" YARN_RESOURCEMANAGER_GC_LOG_OPTS
export YARN_RESOURCEMANAGER_OPTS="$YARN_RESOURCEMANAGER_OPTS $YARN_RESOURCEMANAGER_GC_LOG_OPTS"
# get options for GC logging for YARN AT servers and put them into use
yarn_gc_log_opts_for_component "timelineserver" YARN_TIMELINESERVER_GC_LOG_OPTS
export YARN_RESOURCEMANAGER_OPTS="$YARN_RESOURCEMANAGER_OPTS $YARN_RESOURCEMANAGER_GC_LOG_OPTS"
In the above, you can change {{yarn_log_dir_prefix}}/$USER to wherever you want the GC logs to go (you probably want it to go the the same place as YARN RM and AT server logs). You can change the log file naming too.
If you are managing your Hadoop cluster with Apache Ambari, then these changes would be in YARN service > Configs > Advanced > Advanced yarn-env > yarn-env template. With Ambari, {{yarn_log_dir_prefix}} will be automatically replaced with the YARN Log Dir Prefix defined a few rows above the field.
GC logging will start happening upon server restart.

Storing mapreduce intermediate output on a remote server

I use a hadoop (version 1.2.0) cluster of 16 nodes, one with a public IP (the master) and 15 connected through a private network (the slaves).
Is it possible to use a remote server (in addition to these 16 nodes) for storing the output of the mappers? The problem is that the nodes are running out of disk space during the map phase and I cannot compress map output any more.
I know that mapred.local.dirin mapred-site.xml is used to set a comma-separated list of dirs where the tmp files are stored. Ideally, I would like to have one local dir (the default one) and one directory on the remote server. When the local disk fills, then I would like to use the remote disk.
I am not very sure about about this but as per the link (http://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml) it says that:
The local directory is a directory where MapReduce stores intermediate data files.
May be a comma-separated list of directories on different devices in
order to spread disk i/o. Directories that do not exist are ignored.
Also there are some other properties which you should check out. These might be of help:
mapreduce.tasktracker.local.dir.minspacestart: If the space in mapreduce.cluster.local.dir drops under this, do not ask for more tasks. Value in bytes
mapreduce.tasktracker.local.dir.minspacekill: If the space in mapreduce.cluster.local.dir drops under this, do not ask more tasks until all the current ones have finished and cleaned up. Also, to save the rest of the tasks we have running, kill one of them, to clean up some space. Start with the reduce tasks, then go with the ones that have finished the least. Value in bytes.
The solution was to use the iSCSI technology. A technician helped us out to achieve that, so unfortunately I am not able to provide more details on that.
We mounted the remote disk to a local path (/mnt/disk) of each slave node, and created a tmp file there, with rwx priviledges for all users.
Then, we changed the $HADOOP_HOME/conf/mapred-site.xml file and added the property:
<property>
<name>mapred.local.dir</name>
<value>/mnt/disk/tmp</value>
</property>
Initially, we had two, comma-separated values for that property, with the first being the default value, but it still didn't work as expected (we still got some "No space left on device" errors). So we left only one value there.

Reduce Memory Usage from 16GB to 8GB - Oracle

I had created a oracle instance using "Database Configuration Assistant". My system is having 64GB RAM. I had given 16GB to oracle instance, in Initialization Parameters Wizard.
Now i want to reduce that 16GB to 8GB. So that, the RAM occupied by oracle will be 8GB. I had tried this in SQL Developer,
ALTER SYSTEM SET pga_aggregate_target = 8289 M;
ALTER SYSTEM SET sga_target = 1536 M;
I had restarted the oracle service. It not got reflected. Still the oracle is using 16GB.
I dont know whether this is correct. Whether system reboot is needed for this.? or else how to reduce the memory usage.
There are various ways to define the amount of memory used. Historically, you needed a lot of settings to change to impact total memory footprint. Nowadays, it is often by default setting only one and start tweaking later (when the Oracle installer does not screw up; it often sets things wrongly).
I would check the following:
select *
from v$parameter
where name like '%size%'
or
name like '%target%'
Check which ones have been set and need changing. It can be settingslike shared_pool_size, memory_target, sga_target, and others.
When you change it, some settings (depends on version and edition) can be changed while the instance is open and running, while some require a restart. Also, sometimes you are using a text file (pfile) and in some instance you may be using a binary file (spfile). Binary file is pre-condition to allow online changing without restarting.
You will probably succeed using something like:
alter system set NAME = VALUE scope=[spfile|both]
as sys user. Scope=spfile only changes the spfile, both changes runtime and spfile. When using a pfile like init*.ora, you just edit the text file and restart your instance.
To quickly restart, the best way is IMHO:
startup force
Please decreasing size, you will generally not have a problem assuming that the size is sufficient to handle the load. Do it in a test environment first. When increasing and depending on platform, please make sure first that your new settings can be handled. For instance, increasing memory allocated on Linux may require you to change kernel settings. Otherwise, your Oracle instance will not start unless the corrections are made first.

WAL files in HBase

In HBase before writing into memstore data will be first written into the WAL, but when i checked on my system
WAL files are not getting updated immediately after each Put operation, it's taking lot of time to update. Is there any parameter i need to set?
(WAL has been enabled)
Do you know how long it takes to update the WAL files? Are you sure the time is taken in write or by the time you check WAL, it is already moved to old logs. If WAL is enabled all the entries must come to WAL first and then written to particular region as cluster configured.
I know that WAL files are moved to .oldlogs fairly quickly i.e. 60 seconds as defined in hbase-site.xml through hbase.master.logcleaner.ttl setting.
In standalone mode writing into WAL is taking a lot of time, where as on pseudo distributed mode it's working fine

Resources