`

在Ubuntu Server 8.10上搭建Hadoop-0.19.0环境

阅读更多
在Ubuntu Server 8.10上搭建基于Hadoop-0.19.0的分布式运行环境
(VMware workstation版)


    长期以来,一直很喜欢研究分布式的技术,也一直想尝试搭建一个分布式编程环境,最近看到一些文章讨论Hadoop很多,而且也看到Google也使用Hadoop开发了搜索引擎,因此想尝试着自己也弄一个玩玩,在网上查到了几篇文章讨论了Hadoop环境的搭建,但是讲的都不是很明白,我跟随这些文章Step by step,本以为会是很顺利,但是却遇到诸多磕磕绊绊,很棘手,在网上查了很久,试了很多方法,走了很多弯路才最终解决。好在所有问题都解决了,昨天晚上,终于把环境搭起来,并运行了一遍,Hadoop的Wordcount例子,很顺利地通过了,今天准备把自己的这些天的“搭建之旅”,讲出来,算是给自己的工作做一个注解吧。



    之所以选择Ubuntu,是因为这个操作系统很简洁,很容易配置,而且占用硬盘空间比较小,我的T61上2G内存支持2个虚拟机Ubuntu服务器是没问题的,而且速度很快,虚拟机环境我选择的是VMware-workstation-6.5.1-126130,官网上Download的。开始在我的XP Professional上安装VMware,并在它上面安装Ubuntu Server 8.10,一切都很顺利,都是默认设置,包括硬盘(8G)和内存(512M)分配等,配置低可要吃苦头哦,值得一提的有两点,



1、Ubuntu在安装时候需要把SSH Server安装上,这样免得你以后安装SSH软件比较麻烦,因为Hadoop是通过SSH来与各个机器通讯的。安装时候记得不不要安装Ubuntu自带的JDK,也就是Virual Machine Host(BSD OpenJDK),没用,我们需要的SUN JDK。

2、是网络配置,现在网上很多讲VM上网络配置的文章,我看了好几篇都没有看明白,也是因为自己一直没有碰过VMware。别的不说了,我只说一下我的经历吧,我在家里搭建了一个环境,在单位也搭建了一个环境。家里的是宽带PPPoE上网的,单位是静态IP的局域网通过代理上网。由于我不想用NAT上网,所以就都用了Bridged的方式,而且都是Replicated physical network connection state,这种方式使得虚拟机都在独立存在于网上的,容易访问,有种看得见摸得找的感觉。

网址的配置

家里:我使用的是DHCP动态分配网址,配置文件/etc/network/interfaces,我没有改动,就是:
iface eth0 inet dhcp
auto eth0

单位:修改了/etc/network/interfaces,添加了IP地址,子网掩码,网关。
iface eth0 inet static
address 10.8.83.200
netmask 255.255.255.0
gateway 10.8.83.254
auto eth0

命令如下:sudo vi /etc/network/interfaces,至于vi的操作命令俺在这里就不说了,自己上网查吧。

DNS配置:

家里的配置,我也没有管,也是自动获取的。而单位的配置是修改了/etc/resolv.conf文件。在文件的最末行添加了以下代码:nameserver 10.8.83.11。

还有重要的两个配置需要注意:
1、需要配置/etc/hostname:
命令如下:sudo /etc/hostname
改掉localhost,换成,你自己喜欢的名字,如我的就是ubuntu1,这样你安装的系统就有了一个主机名了,但是一定唯一。

2、需要配置/etc/hosts
命令如下:sudo /etc/hosts
打开这个文件在文件第一行会显示如下文字:
127.0.0.1               localhost
下面的文字不要看。添加上一行如下:
127.0.0.1               ubuntu1.localdomain   ubuntu1
然后保存文件。如果你是静态IP,将127.0.0.1换成你所指定的IP,如果你是动态DHCP的IP,那么你需要查找到动态分配给这个虚拟机的IP,然后替换127.0.0.1。

这样网络配置就完成了,重启网络使之生效:sudo /etc/init.d/networking restart


由于单位是通过代理来上网的,因此单位还需要配置代理,代理在安装的时候我就配置过,可一上网就连接不上,我估计是配置错了,上网一查,很多人说如果设置全局代理,可以在profile里增加配置。其实我的需求很简单,就是能apt update就可以了,因此选择修改~/.bashrc,在.bashrc文件末尾添加如下内容(根据你的实际情况替换yourproxyaddress和proxyport):
export http://[user:password]@yourproxyaddress:proxyport。

使用的命令如下:sudo vi ~/.bashrc

这样在家里和单位尝试 ping www.sohu.com,都可以ping通。没问题。

配置好了网络就开始,安装更新代码和JDK。我首先sudo apt-get update,这个命令使得Ubuntu在更新源下载了很多更新代码,时间好长,建议大家修改一下更新源的配置。

如果你没有安装SSH Server那么可以用以下命令来安装:
sudo apt-get install openssh-server openssh-client
停止ssh: /etc/init.d/ssh stop
启动ssh: /etc/init.d/ssh start
重启ssh: /etc/init.d/ssh restart
安装了ssh,你也可以用SecureCRT访问Ubuntu比直接登录方便些。

接着开始安装JDK,安装的时间也很长,默认的下载源很不稳定,时而300KB,时而300B,简直熬人呀!

命令是:
sudo apt-get install sun-java6-jdk,如果你不确定是不是已经安装过了JDK,可以用命令:java -version来看看。
如果说,java version不是sun的,或者是说java不是内部命令,那么就需要安装了。

值得一提的是,配置环境变量,一般的安装JDK是默认是安装到/usr/lib/jvm/java-6-sun下面的,包括可执行程序以及类库都在这下面,你可以用cd /usr/lib/jvm/java-6-sun命令查看一下。

我配置了两个地方,一个是/etc/environment文件,一个是~/.bashrc文件,分别是这样的:
/etc/environment文件:
CLASSPATH=/usr/lib/jvm/java-6-sun/lib
JAVA_HOME=/usr/lib/jvm/java-6-sun

~/.bashrc的最末行加上
export JAVA_HOME=/usr/lib/jvm/java-6-sun
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=.:$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin

注意:PATH中的$PATH一定要加上,不然你的所有命令如vi,sudo都找不到了。都需要加上/sbin/才能执行。
还有,linux下的配置分隔符是“:”,与Windows下的“;”不一样,这对新手来说尤其重要。

添加完了这些变量,你可以用echo名来查看一下是不是正确的,命令如下:
echo $PATH
echo $CLASSPATH
echo $JAVA_HOME

自己可以看看,是不是与设置的一样。

这时候,执行

现在Ubuntu下面还没有Hadoop,好像我也没有找到Ubuntu下面的Hadoop的安装源,因此,我从官网下载了Hadoop-0.19.0的安装包hadoop-0.19.0.tar.gz到XP下面,我准备想办法把它弄到Ubuntu中去,有两种办法,一是通过共享文件夹,一是通过FTP,我选择了后者。

使用命令:apt-get instal vsftpd,尽管很长时间下载,但是安装很顺利。没有想到,安装完了以后,配置这个ftp目录,却花了我三天时间,主要是自己对于Linux不熟悉,也没有在这个环境下配置ftp的目录,修改了配置文件/etc/vsftpd.conf,但是还是死活上传不了文件,不是告诉我没权限就是告诉我创建文件失败。我的配置文件如下:
anonymous_enable=YES
no_anon_password=YES
local_enable=YES
#这个很重要...
anon_root=/home/ftp/
write_enable=YES
local_umask=022
anon_upload_enable=YES
anon_mkdir_write_enable=YES
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_file=/var/log/vsftpd.log
xferlog_std_format=YES
ftpd_banner=Welcome to blah FTP service.
chroot_local_user=YES
chroot_list_enable=YES
# (default follows)
chroot_list_file=/etc/vsftpd.chroot_list
secure_chroot_dir=/var/run/vsftpd
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.ke

以上有些配置项在默认的配置文件中是没有的,需要用vi命令手动添加,参数的含义我在这里就不讲了,网上一堆一堆的。我的这个配置,主要是考虑到简单化。

还有一个vsftpd.chroot_list文件,添加两行:
anonymous
ftp

这是FTP的两个用户,其实ftp这个用户已经是在安装vsftpd以后就给你默认创建好了的,修改好了配置文件,重启ftp
命令如下:sudo /etc/init.d/vsftpd restart,重启OK。

打开filezilla连接,可以看到ftp的根目录,可以下载,但就是无法上传文件,最后报出一个错误是:
500 OOPS: vsftpd: refusing to run with writable anonymous root
查了好多帖子,都是说东说西,说不到点子上,最后查找到一个帖子,终于搞明白了:
我在anon_root=/home/ftp/设置了一个目录是匿名登录后见到的根目录,上传不能上传到这个目录下面,只能上传在其子目录下面,
我看到贴子上解释这个问题用了很多的叹号,可见,这个问题困扰了不止我一个人,应该是很多人呀。

修改目录的权限:sudo chmod 555 /home/ftp
创建一个子目录:sudo mkdir /home/ftp/upload
修改这个目录的权限属性:sudo chmod o+w /home/ftp/upload
有人说还需要,修改目录的所有者属性,sudo chown ftp upload,但是我没有用这个命令,因为这是修改所有者命令,如果执行了这个命令,那么上面的修改权属的命令就不用执行了。

最后,当看到文件上传的绿色进度条时候,我兴奋得大喊一声,好不容易呀,终于成功了!


上传文件成功了以后,将文件从/home/ftp/upload/拷贝到/home/cdh/下面,然后用tar命令解压该文件,命令是:
sudo tar -xzvf hadoop-0.19.0.tar.gz

然后,将在/home/cdh/hadoop-0.19.0/解压后的文件。这里要注意了,我们使用:ls -lrt命令查看解压后的目录时,可见:
cdh@ubuntu1:/home/cdh$ ls -lrt
drwxr-xr-x 12 root  root         4096 2008-11-14 11:14 hadoop-0.19.0
-rw-------  1 root  nogroup  42266180 2009-01-18 02:59 hadoop-0.19.0.tar.gz

这个文件夹是root所有的,如果一直是root所有,那么在后边将会无法启动hadoop dfs,所有者必须改成是当前用户cdh的。
命令是:sudo chown -R cdh:cdh /home/cdh/hadoop-0.19.0/

第一个当前cdh是用户名,第二个cdh是组名,也就是系统存在一个cdh组,组中有一个用户名是cdh,这是Ubuntu安装时候默认建立的。
如果你想看到你改变所有者时该命令chown命令所做的工作,可以用以下命令:
sudo chown -vR cdh:cdh /home/cdh/hadoop-0.19.0/

执行完成以后,我们再执行命令:ls -lrt,得到的结果是:

drwxr-xr-x 14  cdh  cdh      4096 2009-01-19 02:59 hadoop-0.19.0
-rw-------  1 root root  42266180 2009-01-18 03:59 hadoop-0.19.0.tar.gz

这就为以后,启动hadoop创造了条件。

现在需要配置ssh,因为hadoop是通过ssh来启动所有的slaves,命令如下:
sudo ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa

显示结果如下,一路回车,具体就不解释了,参照ssh的相关文档。
Generating public/private rsa key pair.
Enter file in which to save the key (/home/cdh/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/cdh/.ssh/id_rsa.
Your public key has been saved in /home/cdh/.ssh/id_rsa.pub.
The key fingerprint is:
2e:57:e2:bf:fd:d4:45:5c:a7:51:3d:f1:51:3c:69:68 cdh@ubuntu1

再创建一个authorized_keys文件:
sudo cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

cat命令本来是是用来显示文件文件内容的命令,但是这里作为生成文件的命令,表示一种追加某文件的内容到另一个文件中。

然后用ssh localhost来测试一下是不是ssh连接本机不再需要密码了,第一次连接会出现以下提示:

The authenticity of host [ubuntu1] can't be established. The key fingerprint is: 74:32:91:f2:9c:dc:2e:80:48:73:d4:53:ab:e4:d3:1a Are you sure you want to continue connecting (yes/no)?

输入yes后回车。然后再次ssh localhost将不再需要密码。


剩下的就是配置hadoop的配置文件了。我欣喜地把这些文件copy下来,并保存成hadoop-site.xml文件,上传到/home/cdh/hadoop-0.19.0/conf/下面,然后修改conf/hadoop-env.sh,修改了export JAVA_HOME=/usr/lib/jvm/java-6-sun,并把前面的注释#号去掉。

由于hadoop是运行在多个server上的编程框架,因此我们利用VMware来clone虚拟机,我由于担心三个虚拟机拖垮我的小黑,于是只clone了一个,并将clone机命名为ubuntu2。虚拟机clone完成以后,需要修改两个机器的/etc/hosts,别忘了修改clone机的hostname文件。

对于每一台虚拟机hosts的设置如下:
127.0.0.1               localhost
192.168.158.102         ubuntu1.localdomain   ubuntu1
192.168.158.103         ubuntu2.localdomain   ubuntu2
192.168.158.101         caodh

最后一行是为了能ping通宿主机。同时在宿主机上也按上面进行配置。重新启动两台机器的网络:
sudo /etc/init.d/networking restart

执行结果显示,ubuntu1重新启动成功,而ubuntu2重新启动失败,报得错误很奇怪:
eth0: ERROR while getting interface flags: No such device

这个执行结果一度让我打了退堂鼓,想重新再装虚机来创建slaves,但是上网搜了一下,还真有这个错误的解决办法!看来我遇到的问题前人都已经解决了,原来是这样的,新克隆的虚拟机镜像的网卡mac地址已经变更。打开虚拟机的.vmx文件,ethernet0.generatedAddress项记录了该虚拟机的mac地址。查看所有适配器信息
ifconfig -a发现除了原来的eth0外,Ubuntu已经将新网卡命名为eth1。
Ubuntu保存网卡mac地址和设备名的配置文件在/etc/udev/rules.d/70-persistent-net.rules网卡的网络配置保存在/etc/network/interfaces该配置文件中只有原来eth0的配置信息。由于我在家里的虚机是dhcp的,因此,我决定删除/etc/udev/rules.d/70-persistent-net.rules。命令如下:
sudo rm /etc/udev/rules.d/70-persistent-net.rules

重新启动ubuntu2,成功获取了一个新的IP,多虚拟机配置成功!

对于每一个虚机你要指定hadoop的节点信息,我把ubuntu1设置成master,ubuntu2设置成slave,相应地修改/home/cdh/hadoop-0.19.0/conf/masters和slaves,把其中的localhost删除,分别设置上ubuntu1和ubuntu2,注意,slaves中可以设置多个slave的,主机名一行一个。

这些配置文件,每一个虚机的都是一样的,只有辛苦一点手动设置上去了。也可以偷懒一下,利用ssh的scp来各个虚机进行copy,命令如下:
scp -r hadoop-0.19.0 cdh@ubuntu2:/home/cdh/hadoop-0.19.0
这样也可以保证每个虚机的部署完全一致。

然后,我准备启动hadoop,首先格式化dfs,命令是:
cd /home/cdh/hadoop-0.19.0
bin/hadoop namenode -format,执行结果,抱错!想来想去是不是那地方配置不对?感觉也不是呀,打开来配置文件仔细看,也没有看出问题,后来恍然大悟,linux下文本文件和windows下的文本文件中对于换行符的定义不一致,于是用vi打开hadoop-site.xml,仔细看,发现的确文件中多出了很多的^M字符,删除之!保存,再次格式化,创建log目录都permission denied!这就是我上面所说过的问题,/home/cdh/hadoop-0.19.0/目录的所有者是root,如果按照我上面所讲的,改成了cdh所有,那么就没这个问题了。再次执行格式化,格式化成功!

启动hadoop,是用命令:bin/start-all.sh,又报错,告诉我无法连接上slave,而且告诉我ubuntu2,Deprecated,我百思不得其解,翻看了几个关于hadoop的文章,都没有讲,仔细阅读了hadoop-default.xml文件才知道,

<property>
  <name>fs.default.name</name>
  <value>ubuntu1:9000</value>
  <description>/description>
</property>

中,ubuntu1前面一定要加上hdfs://,即:


<property>
  <name>fs.default.name</name>
  <value>hdfs://ubuntu1:9000/</value>
  <description>/description>
</property>

于是乎我的完整的配置如下:

启动hadoop命令:bin/start-all.sh,启动成功!ubuntu1上namenode,secondary namenode,jobtracker进程,ubuntu2上datanode, tasktracker进程。

如果你想查看这些进程可以使用命令:lsof -i:9000/lsof -i:9001。

至此,hadoop的环境就算配置成功了。下面我用hadoop提供的example验证了一下我配置的环境。

cdh@ubuntu1: $ mkdir -p /home/test-in
cdh@ubuntu1: $ cd test-in
cdh@ubuntu1: $ echo "hello world bye world cdh" >file1.txt 
cdh@ubuntu1: $ echo "hello hadoop goodbye hadoop" >file2.txt
# 请先将待测的文件放到本地文件系统的/home/test-in目录
cdh@ubuntu1: $ cd /home/cdh/hadoop-0.19.0
cdh@ubuntu1: $ bin/hadoop dfs –put /home/test-in input
# 将本地文件系统上的 /home/test-in 目录拷到 HDFS 的根目录上,目录名改为 input
cdh@ubuntu1: $ bin/hadoop jar hadoop-0.19.0-examples.jar wordcount input output
#查看执行结果:
# 将文件从 HDFS 拷到本地文件系统中再查看:
cdh@ubuntu1: $ bin/hadoop dfs -get output output
cdh@ubuntu1: $ cat output/*
# 也可以直接查看
cdh@ubuntu1: $ bin/hadoop dfs -cat output/*
bye     1
cdh     1
goodbye  1
hadoop  2
hello    2
world   2


测试成功!

参考文献:

1、用Hadoop进行分布式并行编程(第1、2、3部分).IBM Cao Yuzhong. URL: http://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop1/index.html

2、分布式计算开源框架Hadoop入门实践. 岑文初.URL: http://tech.ddvip.com/2008-09/122172661667224.html

3、Getting Started with Hadoop. url: http://huang.yunsong.net/2006/getting_started_with_hadoop_part1.html
分享到:
评论

相关推荐

    Ubuntu 8.10下Hadoop-0.20.1集群配置详细手册

    ### Ubuntu 8.10 下 Hadoop-0.20.1 集群配置详细手册 #### 一、集群网络环境介绍 集群由三个节点组成:1个Namenode和2个Datanode,这些节点通过局域网连接,确保它们之间能够互相ping通。以下是各节点的IP地址分配...

    Ubuntu 8.10下Hadoop-0.20.1集群配置手册

    每台节点上运行的都是 Ubuntu 8.10 操作系统,并且都有一个共同的用户 zkl(该用户是在安装 Ubuntu 时创建的首个用户,并具有管理员权限)。在 `/home/zkl/` 目录下,存在一个 `hadoopinstall` 目录,用于存放 ...

    ubuntu-8.10-dvd-i386.iso.torrent

    标题中的"ubuntu-8.10-dvd-i386.iso.torrent"表明这是一个与Ubuntu操作系统相关的文件,具体是Ubuntu 8.10(代号Intrepid Ibex)的DVD安装镜像的torrent文件。Ubuntu是由Canonical公司维护的开源Linux发行版,广泛...

    Ubuntu PPPOE Server环境搭建说明.pdf

    Ubuntu PPPOE 服务器环境搭建是指在 Ubuntu 操作系统中搭建一个 PPPOE 服务器,以便于提供高速的上网服务。下面将详细介绍 Ubuntu PPPOE 服务器环境搭建的步骤。 一、安装 PPPOE 服务器 首先,需要安装 PPPOE ...

    ubuntu8.10下gmlive0.21-1的32位deb包

    gmlive是国人开发的一款运行在linux操作系统下的网络电视,支持mms,sopcast等。此软件来自ubuntu中文社区,支持32位ubuntu8.10系统,版本为gmlive0.21-1。

    Hadoop配置手册Ubuntu8.10

    【Hadoop配置手册Ubuntu8.10】是一个详细的指南,主要涵盖了在Ubuntu 8.10操作系统上安装和配置Hadoop 0.20.1的步骤。以下是配置过程的关键知识点: 1. **系统环境准备**: - 配置环境涉及到三台机器,分别作为...

    wine_1.1.10~winehq0~ubuntu~8.10-0ubuntu1_i386.debwine_1.1.10~winehq0~ubuntu~8.10-0ubuntu1_i386.wine_1.1.10~winehq0~ubuntu~8.10-0ubuntu1_i386.deb

    wine_1.1.10~winehq0~ubuntu~8.10-0ubuntu1_i386.deb

    pcre-8.10.zip

    1. **安装**: 在Linux上,通常通过包管理器来安装PCRE库,如在Ubuntu/Debian系统中使用`sudo apt-get install libpcre3-dev`,在CentOS/Fedora中使用`sudo yum install pcre-devel`。如果使用的是源码安装(即从pcre...

    Python库 | lukeparser-0.3.8.10-cp37-cp37m-manylinux1_x86_64.whl

    资源分类:Python库 所属语言:Python 资源全名:lukeparser-0.3.8.10-cp37-cp37m-manylinux1_x86_64.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    ubuntu 8.10的配置

    在Ubuntu 8.10中,联网配置变得更加用户友好。如果在安装时未联网,系统会提示语言支持不完整,但可以稍后解决。右键点击Gnome面板上的网络连接图标,选择“编辑连接”。在这里,你可以看到多种网络接入方式的配置...

    Alibaba-Dragonwell-8.10.11-aarch64-linux.tar

    《Alibaba Dragonwell JDK在Linux aarch64平台上的安装与使用详解》 Alibaba Dragonwell,由阿里巴巴开源,是一款高性能、稳定且兼容OpenJDK的Java开发工具包(JDK),其版本号为8.10.11,特别针对aarch64架构的...

    UBUNTU8.10安装与配置

    Ubuntu 8.10 安装与配置 本文档将指导您从头开始安装和配置 Ubuntu 8.10操作系统,并对 SSH 服务器和 Samba 文件共享进行配置。 一、Ubuntu 8.10 安装 1. 首先,设置好光盘启动后,放入 Ubuntu 光盘,重启动...

    logstash-8.10.4-windows-x86_64.zip

    在 8.10.4 版本中,可能包含了对这些输入插件的改进和优化,以增强稳定性和性能。 2. **过滤(Filters)**:这一阶段允许用户对收集的数据进行清洗、转换和解析。例如,grok filter 可以解析复杂格式的日志,date ...

    filebeat-8.10.4-windows-x86-64.zip

    在本例中,我们讨论的是 Filebeat 的 Windows 平台上的 x86_64(64位)版本,具体为“filebeat-8.10.4-windows-x86_64”。 1. **Filebeat 简介** Filebeat 是由 Elastic 公司开发的,它是 Beats 家族的一部分,...

    hadoop完全分布配置指南

    本指南已经在Ubuntu 8.10上进行了测试验证,对于其他Linux发行版,配置步骤大体相似。 ##### 1.1 JDK安装 - **安装JDK6:** - 打开终端,执行如下命令来安装Sun JDK6: ```bash sudo apt-get install sun-java6-...

    VPC2007上安装Ubuntu.v8.10

    - 使用ISO镜像文件`ubuntu-8.10-server-i386.iso`引导虚拟机。 **步骤3:选择语言** - 同桌面版一样,这里也可以选择英语或简体中文作为安装语言。 **步骤4:添加启动参数** - 按F6键添加启动参数,在命令行尾部...

    nessus-8.10-64.zip

    安装包是用于在Kali Linux上部署Nessus服务的Deb格式软件包,而readme.txt通常会包含安装指南、使用说明或开发者的一些重要提示。 Nessus的主要功能包括但不限于: 1. **漏洞扫描**:Nessus能够扫描网络中的设备,...

    Hadoop配置手册

    本手册将详细介绍如何在三台Ubuntu服务器上进行Hadoop集群的配置。 **假设环境:** - **Master节点:** IP地址为192.168.1.138,命名为`hadoop-master`。 - **Node节点1:** IP地址为192.168.1.140,命名为`hadoop-...

Global site tag (gtag.js) - Google Analytics