Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"OutOfMemoryError" when importing big amount of entities #104

Open
N2oo opened this issue Dec 12, 2023 · 3 comments
Open

"OutOfMemoryError" when importing big amount of entities #104

N2oo opened this issue Dec 12, 2023 · 3 comments

Comments

@N2oo
Copy link

N2oo commented Dec 12, 2023

Hi,

To reproduce :

use symfony typesense:import --max-per-page=10000 on large amont of values from your database to typesense.
Crash appened close to 15000 Entities in memory.

Reason :

The process throw a fatal error : OutOfMemoryError from Doctrine's classes because Entity manager isn't cleared.

Here is the fact : You must detach Objects from Doctrine by clearing the entity manager.
$this->em->clear()
Here is the ressource that made me think about it.
https://www.doctrine-project.org/projects/doctrine-orm/en/2.14/reference/batch-processing.html

Suggestion :

Here is the change i made from the ImportCommand class :

private function populateIndex(InputInterface $input, OutputInterface $output, string $index)
   {
       /*...*/

       for ($i = $firstPage; $i <= $lastPage; ++$i) {
           $q = $this->em->createQuery('select e from '.$class.' e')
               ->setFirstResult(($i - 1) * $maxPerPage)
               ->setMaxResults($maxPerPage)
           ;

           if ($io->isDebug()) {
               $io->text('<info>Running request : </info>'.$q->getSQL());
           }

           $entities = $q->toIterable();

           $data = [];
           foreach ($entities as $entity) {
               $data[] = $this->transformer->convert($entity);
           }

           $io->text('Import <info>['.$collectionName.'] '.$class.'</info> Page '.$i.' of '.$lastPage.' ('.count($data).' items)');

           $result = $this->documentManager->import($collectionName, $data, $action);


           if ($this->printErrors($io, $result)) {
               $this->isError = true;

               throw new \Exception('Error happened during the import of the collection : '.$collectionName.' (you can see them with the option -v)');
           }

           $populated += count($data);
           $this->em->clear(); //clear every iterations
       }
       $this->em->clear();//clear cache after processing all data

       $io->newLine();
       return $populated;
   }

I've made a fork using this edit, everything seem's ok :
I didn't noticed big performance issues.

Hope it could help,
Have good day.

Originally posted by @N2oo in #74 (comment)

@N2oo N2oo changed the title "OutOfMemoryError" when importing big amount of values "OutOfMemoryError" when importing big amount of entities Dec 12, 2023
@N2oo
Copy link
Author

N2oo commented Dec 12, 2023

Only crashing with my suggestion in prod env.

Looking forward for solution.

@james2001
Copy link
Contributor

Hello @N2oo

Can you try with https://github.com/kiora-tech/TypesenseBundle?
I add this optimisation #96

@MrLexisDev
Copy link

That's the way. Thanks to you, it works. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants