J'ai écrit un article qui fait d'InputStream une entrée pour Lambda.
J'ai essayé le type d'entrée / sortie de Java Lambda ~ Stream version ~ https://qiita.com/kazfuku/items/6f0f55ffa3a88d76cfaa
L'avantage d'utiliser InputStream est qu'il peut gérer d'énormes JSON. Alors, j'ai essayé de vérifier ce que c'était réellement.
Tout d'abord, j'ai préparé un énorme JSON. Les données contiennent 6000 objets avec le nom et le texte, soit environ 5,9 Mo, ce qui est proche de la limite de taille d'entrée de Lambda de 6 Mo.
{
"data":[
{
"name":"vrZPwIw3T7","text":"Ku7aQqW3WzUeiRdXnNB26iVElWdOUj8mQhvHksvN1sMmQ2fT3M8navvbTJuspda2q0bY3FWvsDoguE33tTNtoxuiHjdkUIHmylIezYGitmhJ2bbgcHhcHPzGr4eg3Ger9EijFU82Sq4WS9G5UVW62Cw1rDMNdIld2yxn1Zd3DXqE26iOf1IaBQTzEG7Pld03hkXIkAdTdeAjXlAJlGrwnQgjMh1FohW1bUAYeaLi52qLnbgQd7lZAJuOlitfGUyUbP0BjbsPflOLGQwInPjr2Mt3mG4HDokWj2JJgRkXkRYxq34AxQGNWXjlfWKViDxk2InIP6oMsir5YmTL1oO58dzmBGCoYV7e0PTGQHXJbgPJUFUoCmv3mATCEg1xhOa4IUcP7vC7dMvydS3Qt1QHteYajeCvXiW0HjuHkm2oJ61yEg6JocqLVMQ75RaU0Wjb2KvbAwQmggSel5E6mMl0BacZwBXw7OaYHkHO1p1hQup2hhNkaAkN7B8NS8QJ3oSRPQsM6QsETC3x1ErrN0jZZVqupjDvPEr9xj0fDOpqCo7XqTuSPbf3UhHQgjPyikbc2JaqeMdJf1R0RojlqWmf2STGH8HTuGJTQG3vEP04BkrNLaKNVoXE49tPyePO6EqRAKWNxVZoQmw34Xv6yGzMfOLPcSRhML0rYk1FEaBDmgGNpQIPdYjbT3MC08eEY9cHa813iWvm42XmG5LaiIt2z4IcGaWnLwCRytYJJsdqphSEhyvyOpIKM4i02t9rx3Pkt0704EhFo3SD8gVVIE2y1coFUJqy2GxVqptZrKpFv56c4SsWSPqdLqTH9Gh09Y5Cph6eOKg0JXvip1GoONZ80oBUeRudMvsl32m23fYZlG1dNFnGUZSkz2TiGP9baIfLyPWCcPZGEvVaP9FR64FW0yOLvpKyTNYXg21ZsgEkYo3tbcn3AS5R3Ai4eg5hYMaBoVAsMBK1BPZAncDoqOs97nLa2DZFyqgNSz8Asgmh"
},
{
"name":"OXJIXTP9dz","text":"HkWP0PumYHQZxiGNhGWASXOPrygri7cKXs2hrWx0WaumM8OEVc9UKs2EIknzCsBmAMFRER5YNIUs5oz30LjDrjn1PsoKuh60KPOEaHnBNTt8PivYx0hIfmLoLk56ad6LSLNpUVMCP26WiPyont6OjfD1c4sxtKn3qlg6SaNSs2B1tGoReVb3pwOVvPH2BaULL5rzYyDFfAqFqo4D2UevrdoUOeXK3Ks3tav92wHnECM9pbXdsCbWyr1BNulJ5elcZm8HALPgBeX9dg0vaqpgITfz3klyYIWynzPOJC92t0vMao2tL7lr6uxuQvldWgdhlzGjYP123pdWb2h0zItg8NyyK58tCKy2t2YqtdP23fvmVpmOFygiM6kF9LvDRfnu3mz0X2SvcsQh8UqB84dHiOXwicmnI6DX47OuPXOUZc0wICql8zit6WvbEmDchKy9M74u9mPaiIxGXBy8FvLEptqqGytywwC3GGYXEpLYZlbxDycrSTtCq6PUuWoUbfsJmZT4iZSvM0aoyVKBE2l23oXhFZpM4fxyyziIVAHP9YsQbHQlvr8adtD3voumsGKcklt4mnNQclQdSLKPKSIGdUlkvhcCO4MZcEpKcmSrFU6naOYGL1geB1CuTYHYuw0x6tc7JudQAEB6IWE8xwTgPWQUM15xTsqsLrBIwZ70MGpCGW8JCw6sqJExsXi6wpJ1I3L43TUG4hJOnEPIHeXTco06zaDiSrqG3LsLuCiHIkqYui1N0fJBRJhVcn2X8dXMnQKxqhISGrnP7TeBBcAhI8qrmNK0k9EV6mECQtN2g8qaRYVqwOqC4kwzMpvPWkUnNQuUZbknLlWOKuVeh0mrjTzIxQkMShqhdt21o75h9rz0DPxvNHkS6jLw7TBprYieZwcO8iIRy1zYFedSXyVktczdEczIebkfDFmjGtDeZw5RuuFUYKDk4U3J5lpmfmf9K3G6LuPeV5soPxL54l8ZxlJGNpP1kZftZeadtms7"
},
...
Tout d'abord, il s'agit d'une implémentation de la méthode Map, et le nombre de données est compté.
Quelle est la méthode Map? -> J'ai essayé le type d'entrée / sortie de Java Lambda ~ Map edition ~
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class MapHugeJsonFunction implements RequestHandler<Map<String, Object>, Map<String, Object>> {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Override
public Map<String, Object> handleRequest(Map<String, Object> event, Context context) {
List<Map<String, Object>> data = (List<Map<String, Object>>) event.get("data");
int count = data.size();
return Collections.singletonMap("count", count);
}
}
Résultat d'exécution (≠ Cold Start)
REPORT RequestId: ac45a98c-be93-49b5-8813-c30ae7d731c9 Duration: 2030.51 ms Billed Duration: 2100 ms Memory Size: 128 MB Max Memory Used: 118 MB
Nous utilisons 118 Mo, ce qui est proche de la mémoire maximale. Il s'agit de l'état dans lequel tout le JSON est en mémoire lorsque la carte à passer au handlerRequest est générée. Si vous ajoutez une logique métier à cela, 128 Mo ne seront pas assez de mémoire.
J'ai essayé le même processus avec la méthode Stream. Avec cette implémentation, vous pouvez traiter tout le JSON sans le mettre en mémoire.
L'API Jackson Streaming (https://github.com/FasterXML/jackson-databind#5-minute-tutorial-streaming-parser-generator) est utilisée pour l'analyse JSON. En XML, c'est la même idée que d'utiliser SAX Parser.
Qu'est-ce que la méthode Stream? -> J'ai essayé le type d'entrée / sortie de Java Lambda ~ Stream version ~
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.Map;
public class StreamHugeJsonFunction implements RequestStreamHandler {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
JsonParser parser = OBJECT_MAPPER.createParser(inputStream);
int count = 0;
boolean inData = false;
boolean inDataArray = false;
JsonToken token;
while((token = parser.nextToken()) != null) {
if ("FIELD_NAME".equals(token.name()) && "data".equals(parser.getCurrentName())) {
inData = true;
}
if (inData && "START_ARRAY".equals(token.name())) {
inDataArray = true;
}
if (inDataArray && "END_ARRAY".equals(token.name())) {
inDataArray = false;
}
if (inData && "END_OBJECT".equals(token.name())) {
inData = false;
}
if (inDataArray && "START_OBJECT".equals(token.name())) {
count++;
}
}
Map<String, Integer> response = Collections.singletonMap("count", count);
OBJECT_MAPPER.writeValue(outputStream, response);
}
}
Résultat d'exécution (≠ Cold Start)
REPORT RequestId: 41f93e2e-e1db-4775-b296-8b280d2696f9 Duration: 871.01 ms Billed Duration: 900 ms Memory Size: 128 MB Max Memory Used: 80 MB
Mémoire améliorée à 118 Mo-> 80 Mo. Le temps de traitement a également été amélioré à 2030 ms-> 871 ms.
Pour les processus qui sont fastidieux à analyser JSON mais ne nécessitent pas toutes les données JSON, la méthode Stream est susceptible d'économiser du temps de traitement et de la mémoire.
Recommended Posts