Impala Bölüm 4: Impala Komutları

Cloudera Impala

Database

Öncelikle database’in ne olduğunu anlayalım:

Database, ilgili tabloları tek bir namespace altında gruplamak için mantıksal (logic) bir varlıktır. Impala üzerinde bir database create ettiğimizde HDFS üzerinde database_name.db adında bir dizin oluşturulur. Tüm internal tablolar, partition’lar ve data file’lar bu dizinin içine kaydedilir.

Şimdi Impala’da database özgü birkaç ifadeye bakalım.

Create

Bir database oluşturmak istediğimizde tipik olarak şu söz dizimini kullanılırız:

Bu komutla db1 isminde bir database oluşturmuş oldum, yani aslında Impala’nın dizini altında db1.db adında bir klasör oluşturuldu ve bununla ilgili metadata da Metastore’a kaydedildi.

Eğer yaratmak istediğiniz database mevcut ise bu bir hataya neden olur. Bu işi programatik olarak yapmak istediğinizde çalışan işin kesilmesini istemezsiniz, bu yüzden hata almamak için yoksa oluştur şeklinde yazılması tercih edilir:

Bu sayede Impala önce database mevcut mu diye bakar, eğer varsa komutu çalıştırmadan bize OK cevabını döner, eğer database zaten mevcut değilse, derhal database’i oluşturur ve bize OK cevabını dönmüş olur.

Ek olarak bir database oluştururken bazı açıklamalar ekleyebiliriz. Örneğin neden oluşturduğumuz ile ilgili not almak isteyebiliriz:

Comment dışında key – value çifti halinde parametreler de ekleyebiliriz:

Describe

Bir database hakkında bilgi edinmek için kullanırız.

Bu komutu işlettiğimizde bize database adı, bulunduğu dizin ve oluşturan kişiyle ilgili bilgileri sağlar. Eğer daha fazla detay görmek istersek, örneğin comment veya properties gibi, o zaman şu söz dizimini kullanmamız gerekir:

Show

Impala üzerindeki database’lerin tam listesini verir.

Use

Impala çalışmaya başladığında default isimli bir database oluşturarak hayatına başlar. Biz de Impala’ya bağlandığımızda varsayılan olarak default database’inde çalışırız. Fakat çalışacağımız database bu olmayacağı için, çalışacağımız database’i değiştirmek istediğimizde USE deyimini kullanırız:

Table

Impala’da iki tür tablo oluşturulabilir, internal ve external. Temelde bir tablo oluşturduğunuzda özellikle external olmasını belirtmediyseniz internal olarak oluşturulurlar.

Internal tablonun metadata’sı ve verilerinin sahipliğini Impala üstlenir. External olarak oluşturulan tablolarda ise sadece tablonun metadata’nın sahipliğini üstlenir. Bu durumdaki en büyük farklılık tablonun silinmesi esnasında oluşur. Internal bir tablonun silinmesi istendiğinde metadata ve veriler silinirken, external tablo’da yalnızca metadata silinir. Bu sebeple external bir tablonun verilerini de HDFS üzerinden silmek ikinci bir iş gerektirir.

Create

Bir tablo oluşturmak istediğimizde şu söz dizimini kullanırız.

Bu tanımla bir internal table oluşturmuş olduk. Eğer external olarak oluşturmak isteseydik:

Database konusunda olduğu gibi işi programatik yapmak isterseniz ve eğer tablo yoksa oluşturulsun istersiniz, herhangi bir hata almak istemezseniz:

Tabii ki yukarıdaki şekilde bir tablo yaratamayız, teknik olarak mümkünse de gerçek dünyada bir işimize yaramaz, bunun için daha bir dizi tanımlama yapmamız gerekir. Örneğin sütun tanımlamalarını yapmamız gerekir:

Sonra ekleyeceğim kısım aslında bu veriler bir dosya içinde saklanacağı için sonlandırılma durumunu belirtmek. Öncelikle dosyanın sonlandırıldırılmış olduğunu belirtmemiz gerekiyor:

ROW FORMAT DELIMITED

Sonrasında ise her satırımızın nasıl sonlandırıldığını belirtmemiz gerekiyor. Buna göre her bir veri satırını ve sütununu ele alacağı için önemli.

Sütunumuzun nasıl sonlandığını yani hangi karakterlerle ayrıldığını belirtmek için:

FIELDS TERMINATED BY ‘,’

Burada virgül ile ayırdığımızı belirtmiş oluyoruz.

Array gibi koleksiyonların nasıl sonlandırıldığını belirtmek için:

COLLECTION ITEMS TERMINATED BY ‘:’

Burada : ile koleksiyonlarımızı ayırdığımızı belirtmiş oluyoruz.

Her bir satırın nasıl sonlandığını belirtmek için:

LINES TERMINATED BY ‘\n’

Burada \n yeni bir row ile anlamına geliyor.

Son olarak ne tür bir dosya formatında tutmak istediğimizi söylüyoruz. Default olarak textfile seçilidir; ama bunun dışında SequenceFile, Parquet, Avro, RC, ORC gibi dosya formatlarını da kullanabilirsiniz. Biz textfile seçelim şimdilik:

STORED AS TEXTFILE;

Son hali şöyle olacak:

Aslında bu işin uzun yolu. Eğer internal table oluşturacaksak ve bunu yukarıdaki gibi default olacak şekilde yapacaksak şu şekilde oluşturabilirdik:

Tabii ki bu internal tablo oldu. Eğer external bir tablo yaratacaksak location yani konum bilgisi de eklememiz gerekiyor. External tablonun kullanacağı dosyanın HDFS yolunu, dosya adını içermeden vermemiz gerekiyor. Örneğin kendi dizinimde bir dosyayı kullanacağımı düşünelim ve bu dosya ext isimli bir dizinin altında olsun. Tanım şöyle olmalı:

LOCATION ‘/user/ferhat/ext’

Burada tek bir dosya olması da gerekmez, ne kadar dosya olursa olsun tümünü içerecek şekilde bir external tablo oluşturulur. Şimdi internal tablomuzu external olacak şekilde değiştirirsek şöyle yazmamız gerekir:

Load Data

Tablomuzu oluşturduk; fakat verimiz elimizde hali hazırda olabilir ve bunu external tablo olarak tutmak istemeyebiliriz. Veriyi sunucu üzerideki lokal bir path üzerinde yüklemek istediğimizi, bunun /home/ferhat/data.text dosyası olduğunu varsayalım ve bunu internal olan table1’e yükleyelim.

Insert Into

Oluşturduğumuz bir tabloya, veri yazmak istediğimizde kullanıyoruz.

Tabii yukarıdaki şekilde eklediğinizde table1 içindeki sütun sayısı kadar giriş yapmış olmanız gerekiyor. Eğer belirli sütunlar için değer gireceksek:

Bunun dışında birden fazla satırı da yanyana yazarak ekleyebilirsiniz:

Son olarak bir tablonun içeriğini başka bir tabloya insert etmek istersek VALUES yerine ilgili tablo SELECT ifadesi yazmak yeterli olur:

CTAS (Create Table As Select)

Bir tablonun verilerini başka bir tablo oluşturarak kopyalamak için kullanılan ifadedir. Kullanımı çok basittir:

Insert Overwrite

Bir tablonun verilerini silip, üzerine yeni verileri yazmak için kullanılır. Bunu neden yapmak isteyelim ki? Evet, mantıklı bir soru. Bunu genelde bir partition verilerini yeniden  yazmak için kullanabiliyoruz. Örneğin bir tablomuz olsun ve günlük partitionlar şeklinde verilerimizi saklıyor olalım. Verileri gün içinde yazarken HDFS’te veriler ufak block’lar halinde tutulabiliyor. Bu da çok fazla dosya sayısı olmasına ve Name Node için gereksiz metadata çoklamasına neden oluyor ve Hadoop için ölümcül sonuçlar doğurabilir. Bu yüzden daha az ve daha büyük boyutlu veri tutmak istenir. Genelde o günün bitiminden sonra yani gece 12’den sonra bir job çalıştırılarak o günün partition’ın yeniden doğru şekilde büyük block’lar halinde yazılmasını sağlarız.

Klasik kullanım şekli:

Gerçek dünyadaki senaryoda ise partition bazında tablonun kendisi yine kaynak olarak gösterilerek kullanılır:

Multi Insert

Bazen bir kaynaktan, birden fazla tabloya duruma göre insert yapmak isteyebiliriz. Bunu normalde tek tek sırasıyla yaparız; ama aslında bir arada yapmamız mümkün. Şimdi elimizde bir tablo olsun, developer ve manager bilgileri içerisinde bulunsun. Biz de manager ve developer’lar için bu verileri ayıralım.

Kaynak tablomuz employee_tbl, manager için: manager_tbl, developer için: developer_tbl isimli iki tablo oluşturalım:

Şimdi de kaynak tablomuzdan verileri ilgili tablolara dolduralım:

Alter Table

Alter Table ifadesi, bir tablonun schema’sını değiştirmek için kullanılır. Örneğin yeni sütun eklemek, sütunların adını değiştirmek, tablo adını yeniden adlandırmak vb.

Add Columns

Yeni sütun eklemek istediğimizde kullanıyoruz:

Change Column

Sütun adını değiştirmek için kullanırız. Tablomuzdaki col2 alanının adını new_col2 olarak değiştirelim:

Change Column After

Bir sütunun yerleşim sırasını değiştirmek için kullanırız. Örneğin col1 sütununu col3 sütunundan sonraya taşıyalım:

Rename

Tablo adını değiştirmek için kullanırız:

Replace

Bu komutla tablodaki mevcut tüm sütun isimleri silinir ve yerlerine belirtilen sıra ile yenilerini verir.

Set Tblproperties

Tablo özelliklerini sonradan ayarlamak için kullanılır. Ör:

Set FileFormat

Bir tablo oluşturulurken tutulacağı dosya formatı belirlenir. Sonradan değiştirmek istersek bu da mümkün elbette. Tablomuzu textfile’dan avro formatına dönüştürelim:

Drop

Bir tabloyu tamamen silmek için kullanırız. Silme işleminde yalnzca internal tablolarda verilerle birlikte tüm metadata’nın silindiğini anımsayalım. Eğer external bir tablo üzerinde bu işlemi yaparsanız sadece metadata’nın silndiğini, verilerin ise HDFS üzerinde klamaya devam ettiğini bilmemiz önemlidir.

Kullanımı:

No_Drop

İsminden de anlayacağınız gibi tablonun yanlışlıkla silinmesine karşı bir önlem olarak kullanılır. Temelde yetkisi olan biri yanlışlıkla tabloyu silme olasılığı mevcuttur ve sizin için hayati veriler içeren önemli bir tablo ise dokunulmasını istemeyebilir ve silinmeye karşı korumalı hale getirebilirsiniz.

Bunun için:

Eğer tekrar silmeye açmak isterseniz:

Offline

Bazen geçici bir süre tablomuza ulaşılmasını istemeyebiliriz. Bu gibi durumlarda kullanımını engellemek için offline hale getirebiliriz. Bunun için:

Eğer tekrar kullanıma açmak istersek:

Truncate

Bir tablodaki tüm verileri silmek için kullanılır:

View

Temel olarak Impala’da view, kendisi herhangi bir veriye sahip olmayan ancak bir sorgunun sonuçlarıyla doldurulabilen, veritabanında bulunan bir tür aranabilir nesnedir. Kısaca view’lerin özelliklerini anlatmak gerekirse:

  • Herhangi bir veri içermezler. Yalnızca Impala’da yürütülen bir sorgunun sonucudur.
  • DML işlemleri view’ler üzerinde gerçekleştirilebilir.
  • Tablo veya tabloların birleştirilmesini içeren bir sorgu ile oluşturulurlar.
  • View’ler oluşturulduğunda kaynak olarak kullanılan tabloların schema’sı değişse de değişmezler, bu sebeple ALTER VIEW komutu ile schema’sının değiştirilmesi gerekir.
  • View drop edildiğinde sadece kendisi silinir, kaynak tablolar silinmezler.
  • Kaynak tabloların silinmesi view’in silinmesine neden olmaz; ama bu durumda view’in kalmasının da anlamı yoktur. Böyle bir durumda view’de ayrıca silinmelidir.

View’in en temel kullanım amacı kullanıcılara uygun çıktılar vermek için uygun bir schema sağlamaktır. Diğer taraftan tablo yapınızın ve hatta tablolarınızı kullanıcıların bilmesini istemiyor olabilirsiniz, bu durumda x database’in olduşturduğunuz bir view ile y database’inden tabloların verilerini kullanıcılara sunabilirsiniz.

Burada bilmeniz gereken en önemli konu, view’e okuma hakkı tanımlasanız da, aynı yetkileri tabloya da tanımlamak zorunda olmanız. View bir veri içermediği için ve temelde kaynak tablodan verileri okuduğu için okuma yetkisini kaynak tabloda da vermeden kullancılara sunamazsınız. Bu şekilde kullanıcılarınızın hata alacağını unutmamalısınız.

Create View

View create etmek için yapı oldukça basittir:

Create view ifadesinden sonra vermek istediğimiz view adı, sonrasında da as ifadesi ve son olarakta çalıştırması gereken sorguyu giriyoruz. Örnek:

Create ederken nesnenin tekil olması gerektiğini yine anımsayalım. Eğer bunu programatik olarak yapacak ve hata almak istemyecek olursanız:

Son bir not olarak burada join gibi işlemleri de yapabileceğinizi ekleyeyim.

Alter View

View’in schema’sını değiştirmek istediğimizde alter komutunu kullanırız:

Yine ismini değiştirmek istersek:

Drop View

Bir view’i silmek istersek:

Sorting

Çoğu zaman tablolarımızdaki verilerimizi sıralama ihtiyacı hissederiz. Sıralama için kullanabileceğimiz söz dizimlerinden burada bahsedeceğiz.

Order By

Sorgunun tamamının sıralanması için kullanırız. Söz dizimi şu şekildedir:

impala> SELECT * FROM table1 ORDER BY col1;

Teoride kolay gibi gözükse de aslında yüksek seviyede bellek tüketimi söz konusudur. Öncelikle Select ifadesi sonucu tüm Impala Daemon’lardan Coordinator’e gider. Coordinator bunları sıralama işlemini de bellek üzerinde yapar, bu sebeple veri seti boyutu ne kadar büyükse, o oranda ram tüketimi yapacak ve sorgu sonucu buna göre daha fazla gecikme yapacaktır. Bu sebeple genelde Limit kullanılması tavsiye edilir.