AnalyticDB for MySQL prend en charge la fonction REMOTE_CALL(), qui vous permet d'appeler directement depuis SQL des fonctions définies par l'utilisateur (UDF) personnalisées hébergées dans Function Compute. Seules les UDF scalaires sont prises en charge.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Un cluster AnalyticDB for MySQL exécutant une version du noyau 3.2.1.0 ou ultérieure
Le cluster et votre service Function Compute situés dans la même région
Pour réduire les temps de démarrage à froid, sélectionnez Python , Go ou Node.js comme Runtime Environment lors de la création de l'UDF.
Fonctionnement
Function Compute agit en tant que serveur de fonctions distant. Lorsque REMOTE_CALL() est invoquée dans une instruction SQL, AnalyticDB for MySQL envoie les données à Function Compute au format JSON et renvoie le résultat au client.
Un client soumet une instruction SQL à AnalyticDB for MySQL.
Après l'appel de
REMOTE_CALL(), AnalyticDB for MySQL transmet les données à Function Compute au format JSON.Function Compute traite les données à l'aide de votre UDF.
Function Compute renvoie le résultat à AnalyticDB for MySQL au format JSON.
AnalyticDB for MySQL retourne le résultat final au client.
Syntaxe
remote_call('returnType', 'func_name', ['{external_config}'|NULL], X1, X2, ..., Xn)
Paramètres
| Paramètre | Description | |
|---|---|---|
returnType |
Type de données de la valeur de retour. Valeurs valides : BOOLEAN, DOUBLE, VARCHAR, INTEGER, TINYINT, BIGINT, TIME, DATE, TIMESTAMP, DATETIME. | |
func_name |
Nom de l'UDF dans Function Compute. Pour Function Compute 3.0, spécifiez uniquement le nom de la fonction. Pour Function Compute 2.0, utilisez le format serviceName$functionName. Connectez-vous à la console Function Compute pour vérifier la version. |
|
external_config |
NULL |
Configuration étendue au format JSON. Spécifiez |
X1...Xn |
Paramètres d'entrée. Valeurs valides : BOOLEAN, DOUBLE, VARCHAR, INTEGER, TINYINT, BIGINT, TIME, DATE, TIMESTAMP, DATETIME. |
Paramètres étendus pour external_config
Définissez les paramètres external_config au niveau de la requête ou configurez-les globalement à l'aide de SET ADB_CONFIG. Les paramètres au niveau de la requête ont priorité sur les paramètres globaux.
| Paramètre global | Paramètre au niveau de la requête | Obligatoire | Description |
|---|---|---|---|
XIHE_REMOTE_CALL_SERVER_ENDPOINT |
endpoint |
Oui | Endpoint de service interne de Function Compute. Pour plus de détails, consultez la section Endpoints de service. |
XIHE_REMOTE_CALL_SERVER_AK |
— | Conditionnel | ID AccessKey du compte Alibaba Cloud ou de l'utilisateur Resource Access Management (RAM) disposant des permissions sur Function Compute. Requis pour les clusters Data Warehouse Edition. Pour les clusters Enterprise Edition, Basic Edition et Data Lakehouse Edition, Security Token Service (STS) gère automatiquement l'authentification pour l'accès au sein du même compte ; l'accès inter-comptes nécessite l'ID AccessKey. Peut uniquement être défini comme paramètre global. Pour plus de détails, consultez la page Comptes et permissions. |
XIHE_REMOTE_CALL_SERVER_SK |
— | Conditionnel | Secret AccessKey du compte Alibaba Cloud ou de l'utilisateur RAM. Mêmes conditions que pour XIHE_REMOTE_CALL_SERVER_AK. Peut uniquement être défini comme paramètre global. |
XIHE_REMOTE_CALL_COMPRESS_ENABLED |
compressed |
Non | Indique s'il faut compresser la charge utile des données au format GZIP avant de l'envoyer à Function Compute. Valeur par défaut : true. |
XIHE_REMOTE_CALL_MAX_BATCH_SIZE |
max_batch_size |
Non | Nombre maximal de lignes envoyées à Function Compute par lot. Valeur par défaut : aucune limite. Une taille de lot plus petite réduit la pression sur le CPU et la mémoire de Function Compute, mais augmente le temps de requête. |
Les paramètres XIHE_REMOTE_CALL_SERVER_AK et XIHE_REMOTE_CALL_SERVER_SK ne peuvent être configurés qu'en tant que paramètres globaux à l'aide de SET ADB_CONFIG.
Écrire un gestionnaire Function Compute
Votre UDF doit accepter les entrées et renvoyer les résultats au format JSON utilisé par REMOTE_CALL().
Exemple : Gestionnaire Java
L'exemple suivant implémente ConcactNumberWithCompress, qui prend deux entiers a et b et renvoie la chaîne "a&b&1".
public class App
implements StreamRequestHandler, FunctionInitializer
{
public static final Logger log = Logger.getLogger(App.class.getName());
public void initialize(Context context) throws IOException {
// TODO
}
@Override
public void handleRequest(
InputStream inputStream, OutputStream outputStream, Context context)
throws IOException
{
// Step 1: Decompress the input.
// REMOTE_CALL() compresses data with GZIP by default (compressed=true).
// If you set compressed=false in external_config, skip this step.
InputStream decompressedInput = tryUnCompress(inputStream);
JSONObject response = new JSONObject();
try {
// Step 2: Parse the JSON body sent by AnalyticDB for MySQL.
// The body has the structure: {"rowCount": N, "compressed": true/false, "data": [[...], ...]}
JSONObject requestJson = JSONObject.parseObject(IOUtils.toString(decompressedInput));
if (requestJson.containsKey("data")) {
JSONArray result = new JSONArray();
// Step 3: Iterate over the rows in the "data" array.
// Each row is a JSON array whose columns match the X1...Xn parameter order in REMOTE_CALL().
// This function expects two integers: X1 (index 0) and X2 (index 1).
JSONArray data = requestJson.getJSONArray("data");
for (int i = 0; i < data.size(); i++) {
JSONArray row = data.getJSONArray(i);
if (row.size() == 2) {
result.add(testFunc(row.getInteger(0), row.getInteger(1)));
} else {
throw new RuntimeException("row size is not 2");
}
}
// Step 4: Build the response.
response.put("result", result);
response.put("success", true);
response.put("message", "");
} else {
response.put("success", false);
response.put("message", "no data inside");
}
} catch (Exception e) {
log.info("error happened" + e.getMessage());
response.put("success", false);
response.put("message", e.getMessage());
}
// Step 5: Compress the response.
// REMOTE_CALL() expects a GZIP-compressed response when compressed=true (the default).
// If you set compressed=false in external_config, remove this compression step.
outputStream.write(tryCompress(response.toJSONString().getBytes()));
}
private String testFunc(int a, int b) {
// Concatenate a, b, and 1 with ampersands.
return String.valueOf(a) + '&' + b + '&' + 1;
}
public static byte[] tryCompress(byte[] bytes) {
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
try {
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteOutputStream);
gzipOutputStream.write(bytes);
gzipOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return byteOutputStream.toByteArray();
}
public static InputStream tryUnCompress(InputStream inputStream) throws IOException {
return new GZIPInputStream(inputStream);
}
}
Exemples
Appel avec configuration au niveau de la requête
Transmettez l'endpoint Function Compute directement dans le paramètre external_config :
-- Concatenate 1 and 2 with an ampersand
SELECT remote_call(
'varchar',
'ConcactNumberWithCompress',
'{endpoint:"1234567890000****.cn-zhangjiakou-internal.fc.aliyuncs.com"}',
1, 2
);
-- Result: 1&2&1
Désactivez la compression GZIP et définissez une limite de taille de lot :
SELECT remote_call(
'varchar',
'ConcactNumberWithCompress',
'{endpoint:"1234567890000****.cn-zhangjiakou-internal.fc.aliyuncs.com",compressed:false,max_batch_size:5000000}',
3, 4
);
-- Result: 3&4&1
Appel avec configuration globale
Configurez les paramètres globaux une fois à l'aide de SET ADB_CONFIG, puis omettez external_config des appels suivants :
SELECT remote_call('varchar', 'ConcactNumberWithCompress', null, 5, 6);
-- Result: 5&6&1
Dépannage
java.util.zip.ZipException: Not in GZIP format
Cette erreur a deux causes courantes :
Incompatibilité de décompression à l'entrée : AnalyticDB for MySQL compresse les données au format GZIP et les envoie à Function Compute, mais la fonction définie par l'utilisateur créée dans Function Compute ne contient pas de code de décompression. Par conséquent, Function Compute ne peut pas analyser les données.
Incompatibilité de compression à la sortie : AnalyticDB for MySQL envoie des données non compressées à Function Compute. Après traitement, Function Compute compresse le résultat au format GZIP et le renvoie à AnalyticDB for MySQL. Par conséquent, AnalyticDB for MySQL ne peut pas analyser les données.
parse remote_call config error
Le JSON external_config est mal formé. Vérifiez la syntaxe de la valeur external_config dans votre instruction SQL, corrigez-la et exécutez à nouveau la requête.