Kullanıcı tanımlı bir toplama işlevi (UDAF), birden çok giriş satırını tek bir çıkış değerine indirger; bu, çoktan bire eşlemedir. Yerleşik toplama işlevleri SUM veya MAX gibi işlevler toplama mantığınızı karşılamadığında UDAF'leri kullanın.
Flink'teki kullanıcı tanımlı işlevler hakkında arka plan bilgisi için bkz. User-defined Functions.
User-defined Functions ve ASI_UDX_Demo üçüncü taraf web sitelerinde barındırılır ve zaman zaman yavaş olabilir veya kullanılamayabilir.
Nasıl çalışır?
Bir UDAF, ara toplama durumunu depolamak için bir akümülatör kullanır. Aynı GROUP BY anahtarını paylaşan her satır grubu için çalışma zamanı üç yöntemi sırayla çağırır:
createAccumulator()— başlangıç durumuyla yeni bir akümülatör oluşturur.accumulate(acc, ...)— akümülatörü güncellemek için her giriş satırı için bir kez çağrılır.getValue(acc)— tüm satırlar işlendikten sonra nihai sonucu döndürmek için çağrılır.
Örneğin, bir tabloda sayısal bir sütun varsa ve aynı gruptaki 1, 2 ve 3 değerleri için kümülatif toplam istiyorsanız:
Çalışma zamanı, akümülatörü
sum = 0değeriyle başlatmak içincreateAccumulator()yöntemini bir kez çağırır.Her satır için
accumulate()yöntemini çağıraraksumdeğerini önce1, ardından3ve son olarak6olacak şekilde günceller.Nihai sonucu döndürmek için
getValue()yöntemini çağırır.
Çıkış, mini toplu iş özelliğinin etkin olup olmadığına bağlıdır:
Mini toplu iş olmadan (varsayılan): Satır başına bir çıkış —
1,3,6.Mini toplu iş etkinleştirildiğinde: Yalnızca nihai sonuç —
6. Ara çıktıların sayısı mini toplu iş ayarlarına ve veri dağılımına göre değişir.
Mini toplu iş yapılandırması için bkz. Flink SQL'i Optimize Etme.
Gerekli yöntemler
Her AggregateFunction uygulaması şu üç yöntemi tanımlamalıdır:
| Yöntem | Amaç |
|---|---|
createAccumulator() |
Başlangıç durumuyla yeni bir akümülatör döndürür |
accumulate(acc, ...) |
Akümülatörü bir giriş satırıyla günceller |
getValue(acc) |
Nihai toplanmış sonucu döndürür |
Kullanım durumunuza bağlı olarak ek yöntemler de kullanılabilir:
| Yöntem | Amaç |
|---|---|
retract(acc, ...) |
Yukarı akış operatörü tarafından oluşturulan bir mesajın geri alınmasını destekler |
merge(acc, iterable) |
Yerel-genel iki aşamalı toplama optimizasyonunu destekler |
UDAF oluşturma
Realtime Compute for Apache Flink, önceden yapılandırılmış bir geliştirme ortamı sunan bir UDF demo projesi (ASI_UDX_Demo) sağlar; bu nedenle ortam kurulumu gerekmez.
Demo projesi, kullanıcı tanımlı skaler işlevler (UDSF), UDAF'ler ve kullanıcı tanımlı tablo değerli işlevler (UDTF) için örnek uygulamalar içerir.
Ön koşullar
Başlamadan önce şunlara sahip olduğunuzdan emin olun:
IntelliJ IDEA yüklü
Maven yüklü
Java geliştirme ortamı yapılandırılmış
Adımlar
-
ASI_UDX_Demo projesini indirin ve yerel makinenizde sıkıştırılmış dosyayı açın. Sıkıştırması açılan
ASI_UDX-mainklasörü şunları içerir:pom.xml— koordinatlar, bağımlılıklar ve derleme kuralları dahil Maven proje yapılandırması.\ASI_UDX-main\src\main\java\ASI_UDAF\ASI_UDAF.java— örnek UDAF uygulaması.
IntelliJ IDEA'da File > Open seçeneklerini seçin, ardından
ASI_UDX-mainklasörünü seçin.-
\ASI_UDX-main\dizinindekipom.xmldosyasını açın ve bağımlılıkları yapılandırın. Dosya, Flink 1.12 için minimum bağımlılığı içerir:İşinizde ek bağımlılık yoksa sonraki adıma geçin.
İşiniz ek bağımlılıklar gerektiriyorsa bunları
pom.xmldosyasına ekleyin.
<dependencies> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-table-common</artifactId> <version>1.12.7</version> <scope>provided</scope> </dependency> </dependencies>Ververica Runtime (VVR) sürümünüzle eşleşen Apache Flink ana sürümü için en son küçük sürümü kullanın. VVR ile Flink sürüm eşlemeleri için bkz. Genel Bakış.
-
\ASI_UDX-main\src\main\java\ASI_UDAF\ASI_UDAF.javadosyasını açın ve toplama mantığınızı uygulayın. Örnek, kümülatif toplamayı uygular:package ASI_UDAF; import org.apache.flink.table.functions.AggregateFunction; import java.util.Iterator; public class ASI_UDAF{ public static class AccSum{ public long sum; } public static class MySum extends AggregateFunction<Long, AccSum>{ @Override public Long getValue(AccSum acSum){ return acSum.sum; } @Override public AccSum createAccumulator(){ AccSum acCount= new AccSum(); acCount.sum=0; return acCount; } public void accumulate(AccSum acc,long num){ acc.sum += num; } /** * Supports retracting a message generated by an upstream operator. */ public void retract(AccSum acc,long num){ acc.sum -= num; } /** * Supports local-global two-stage aggregate optimization. */ public void merge(AccSum acc,Iterable<AccSum> it){ Iterator<AccSum> iter=it.iterator(); while(iter.hasNext()){ AccSum accSum=iter.next(); if(null!=accSum){ acc.sum+=accSum.sum; } } } } } -
pom.xmldosyasını içeren dizinden şu komutu çalıştırın:mvn package -Dcheckstyle.skip\ASI_UDX-main\target\dizinindeASI_UDX-1.0-SNAPSHOT.jardosyası göründüğünde UDAF başarıyla paketlenmiş olur.
UDAF kullanma
SQL dağıtımlarında UDAF kullanmak için iki yöntem mevcuttur. Aşağıdaki tabloda temel farklılıklar özetlenmiştir:
| Yön | Yöntem 1: Kayıtlı UDAF | Yöntem 2: Dağıtım düzeyinde JAR |
|---|---|---|
| Kapsam | Birden çok dağıtımda kullanılabilir | Yalnızca tek bir dağıtım |
| Nasıl kaydedilir | UDF yönetim sayfası üzerinden kaydedin | Dağıtımdaki Additional dependency files altında JAR yükleyin |
| SQL'de nasıl çağrılır | Kayıtlı adla çağırın (CREATE TEMPORARY FUNCTION gerekmez) |
CREATE TEMPORARY FUNCTION … AS 'fully.qualified.ClassName' ile bir takma ad tanımlayın |
| Yeniden kullanılabilirlik | Yüksek — paylaşılan iş mantığı için uygundur | Düşük — tek bir dağıtıma bağlıdır |
Yöntem 1: Kayıtlı UDAF kullanma (önerilen)
UDAF'i bir kez kaydedin, ardından dağıtımlar arasında yeniden kullanın. Kayıt adımları için bkz. UDF'leri Yönetme.
ASI_UDAF$MySum olarak kaydedildikten sonra SQL kodunuzda doğrudan çağırabilirsiniz:
CREATE TEMPORARY TABLE ASI_UDAF_Source (
a BIGINT NOT NULL
) WITH (
'connector' = 'datagen'
);
CREATE TEMPORARY TABLE ASI_UDAF_Sink (
sum BIGINT
) WITH (
'connector' = 'print'
);
INSERT INTO ASI_UDAF_Sink
SELECT `ASI_UDAF$MySum`(a)
FROM ASI_UDAF_Source;
Yöntem 2: Belirli bir dağıtıma JAR yükleme
Flink Data Studio > ETL sayfasında, More configurations altındaki Additional dependency files seçeneğini kullanarak JAR paketini yükleyin. Ardından işin SQL kodunda geçici bir işlev takma adı tanımlayın.
JAR yalnızca o dağıtımla sınırlıdır ve diğer dağıtımlarla paylaşılamaz.
Geçici işlev mysum olarak adlandırılırsa:
CREATE TEMPORARY TABLE ASI_UDAF_Source (
a BIGINT
) WITH (
'connector' = 'datagen'
);
CREATE TEMPORARY TABLE ASI_UDAF_Sink (
sum BIGINT
) WITH (
'connector' = 'print'
);
CREATE TEMPORARY FUNCTION `mysum` AS 'ASI_UDAF.ASI_UDAF$MySum'; -- Create the temporary function mysum.
INSERT INTO ASI_UDAF_Sink
SELECT `mysum`(a)
FROM ASI_UDAF_Source;
İşi çalıştırma
SQL işini geliştirdikten ve dağıttıktan sonra Operation Center > Job O&M bölümüne gidin. Hedef işi bulun ve Operation sütunundaki Start düğmesine tıklayın.
İş başladıktan sonra UDAF, ASI_UDAF_Source tablosundaki a alanını toplar ve kümülatif toplamı ASI_UDAF_Sink tablosuna yazar.
Sonraki adımlar
UDF'leri Yönetme — UDAF'leri kaydedin ve dağıtımlar arasında yeniden kullanım için yönetin.
Flink SQL'i Optimize Etme — Ara sonuçların nasıl yayılacağını kontrol etmek için mini toplu işi yapılandırın.
Genel Bakış — VVR sürümünüzle eşleşen Apache Flink sürümünü bulun.